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         if (matchdata = /\A\/(\d{1,100})(?=\/|\z)/.match(@remaining_path)) && (value = _match_class_convert_Integer(matchdata[1]))
 56           @remaining_path = matchdata.post_match
 57           always{yield(value)}
 58         end
 59       else
 60         path = @remaining_path
 61         captures = @captures.clear
 62         meth = :"_match_class_#{matcher}"
 63         if respond_to?(meth, true)
 64           # Allow calling private methods, as match methods are generally private
 65           if send(meth, &block)
 66             block_result(yield(*captures))
 67             throw :halt, response.finish
 68           else
 69             @remaining_path = path
 70             false
 71           end
 72         else
 73           unsupported_matcher(matcher)
 74         end
 75       end
 76     when Regexp
 77       if matchdata = self.class.cached_matcher(matcher){matcher}.match(@remaining_path)
 78         @remaining_path = matchdata.post_match
 79         always{yield(*matchdata.captures)}
 80       end
 81     when true
 82       always(&block)
 83     when false, nil
 84       # nothing
 85     else
 86       path = @remaining_path
 87       captures = @captures.clear
 88 
 89       matched = case matcher
 90       when Array
 91         _match_array(matcher)
 92       when Hash
 93         _match_hash(matcher)
 94       when Symbol
 95         _match_symbol(matcher)
 96       when Proc
 97         matcher.call
 98       else
 99         unsupported_matcher(matcher)
100       end
101 
102       if matched
103         block_result(yield(*captures))
104         throw :halt, response.finish
105       else
106         @remaining_path = path
107         false
108       end
109     end
110   when 0
111     always(&block)
112   else
113     if_match(args, &block)
114   end
115 end