module Roda::RodaPlugins::OptimizedMatching::RequestMethods

  1. lib/roda/plugins/_optimized_matching.rb

Methods

Public Instance

  1. is
  2. on

Public Instance methods

is(*args, &block)

Optimize the r.is method handling of a single string, String, Integer, regexp, or true, argument.

[show source]
   # File lib/roda/plugins/_optimized_matching.rb
22 def is(*args, &block)
23   case args.length
24   when 1
25     _is1(args, &block)
26   when 0
27     always(&block) if @remaining_path.empty?
28   else
29     if_match(args << TERM, &block)
30   end
31 end
on(*args, &block)

Optimize the r.on method handling of a single string, String, Integer, or regexp argument. Inline the related matching code to avoid the need to modify @captures.

[show source]
    # File lib/roda/plugins/_optimized_matching.rb
 36 def on(*args, &block)
 37   case args.length
 38   when 1
 39     case matcher = args[0]
 40     when String
 41       always{yield} if _match_string(matcher)
 42     when Class
 43       if matcher == String
 44         rp = @remaining_path
 45         if rp.getbyte(0) == 47
 46           if last = rp.index('/', 1)
 47             @remaining_path = rp[last, rp.length]
 48             always{yield rp[1, last-1]}
 49           elsif (len = rp.length) > 1
 50             @remaining_path = ""
 51             always{yield rp[1, len]}
 52           end
 53         end
 54       elsif matcher == Integer
 55         rp = @remaining_path
 56         if /\A\/(\d{1,100})(?=\/|\z)/.match?(rp)
 57           if last = rp.index('/', 1)
 58             value = rp[1, last-1]
 59             rp = rp[last, rp.length]
 60           else
 61             value = rp[1, rp.length]
 62             rp = ""
 63           end
 64 
 65           if value = scope.send(:_convert_class_Integer, value)
 66             @remaining_path = rp
 67             always{yield(value)}
 68           end
 69         end
 70       else
 71         path = @remaining_path
 72         captures = @captures.clear
 73         meth = :"_match_class_#{matcher}"
 74         if respond_to?(meth, true)
 75           # Allow calling private methods, as match methods are generally private
 76           if send(meth, &block)
 77             block_result(yield(*captures))
 78             throw :halt, response.finish
 79           else
 80             @remaining_path = path
 81             false
 82           end
 83         else
 84           unsupported_matcher(matcher)
 85         end
 86       end
 87     when Regexp
 88       if matchdata = self.class.cached_matcher(matcher){matcher}.match(@remaining_path)
 89         @remaining_path = matchdata.post_match
 90         always{yield(*matchdata.captures)}
 91       end
 92     when true
 93       always(&block)
 94     when false, nil
 95       # nothing
 96     else
 97       path = @remaining_path
 98       captures = @captures.clear
 99 
100       matched = case matcher
101       when Array
102         _match_array(matcher)
103       when Hash
104         _match_hash(matcher)
105       when Symbol
106         _match_symbol(matcher)
107       when Proc
108         matcher.call
109       else
110         unsupported_matcher(matcher)
111       end
112 
113       if matched
114         block_result(yield(*captures))
115         throw :halt, response.finish
116       else
117         @remaining_path = path
118         false
119       end
120     end
121   when 0
122     always(&block)
123   else
124     if_match(args, &block)
125   end
126 end