Class Maveric::Route
In: maveric.rb
Parent: Regexp

Instances of Route are used for determining how to act upon particular urls in each Maveric instance. They are magical and simply complex creatures. The Route class was inspired by Merb‘s implementation, which in turn were inspired by Rails. One thing I think Rails has done nicely, to a point.

The String path is turned into a Regexp in a very straight-forward manner. Fragments of the path that begin with ’:’ followed by any number of characters that aren‘t a typical URI delimiter or reserved character, and optionally ending with another ’:’, are indicators of paramæters. The trailing ’:’ is useful if the parameter occurs within a string of similar characters.

Parameters are replaced by default with the regexp of /(#{URI_CHAR}+)/ in the final Route. If a parameter symbol matches a key in the opts hash the associated value is placed into the Route instead.

Methods

__compile   build   inspect   new   reroot   route  

Constants

URI_CHAR = '[^/?:,&#]'   A negative class of URI delimiting and reserved characters.
PARAM_MATCH = %r~:(#{URI_CHAR}+):?~   Standard pattern for finding parameters in provided paths.

Attributes

options  [R] 
params  [R] 
path  [R] 

Public Class methods

NOTE: The following examples shows a return value of the equivalent regexp and not the result of Route#inspect.

  Route.new '/'
    => /^\/$/                # with no groups or derived values
  Route.new '/:value'
    => /^\/([^/?:,&#]+)$/    # with group 1 assigned to :value
  Route.new '/:val:ue'
    => /^\/([^/?:,&#]+)ue$/ # with group 1 assigned to :val
  Route.new '/:value', :value => 'print|find'
    => /^\/(print|find)$/
  Route.new '/:whtevr', :whtevr => '.*'
    => /^\/(.*)$/            # if you want a real catch-all

[Source]

     # File maveric.rb, line 699
699:   def initialize path, opts={}
700:     ::Maveric.type_check :path, path, String
701:     ::Maveric.type_check :opts, opts, Hash
702: 
703:     @path = path.dup.freeze
704:     @options = opts.dup.freeze
705: 
706:     regex, @params = __compile path, opts
707:     @params.freeze
708:     super %r~^#{regex}$~iu
709:     freeze
710: 
711:     ::Maveric.log.debug self.inspect
712:   end

Public Instance methods

If given a hash that contains all of and only contains keys matching its parameters then a path will be built by interpolating the hash values for their corresponding parameters.

NOTE: Should I or should I not pass the result to #route to ensure the generation of a compatible path?

[Source]

     # File maveric.rb, line 723
723:   def build arg
724:     ::Maveric.log.debug "#{self.class}#build #{arg.inspect} : #{@params}"
725:     ::Maveric.type_check :arg, arg, Hash
726:     if @params.sort == arg.keys.sort
727:       path = arg.inject(@path){|r,(k,v)| r.sub /:#{k}:?/, v }
728:     end
729:   end

As Route is a subclass of a corelib class, the inspect isn‘t as informative as we‘d like. So we override it.

[Source]

     # File maveric.rb, line 759
759:   def inspect
760:     "#<%s:0x%x %s %s %s>" % [
761:       self.class,
762:       [object_id<<1].pack('i').unpack('I')[0],
763:       super,
764:       @params.inspect,
765:       @path.inspect
766:     ]
767:   end

This is an attempt as path correction. The String root is treated as a prefix to the generating path to be removed, from which a new Route will be generated.

  r = Route.new '/foo/bar/qux'
  r.reroot('/foo') == Route.new('/bar/qux')
    => true

[Source]

     # File maveric.rb, line 751
751:   def reroot root, opts={}
752:     ::Maveric.type_check :root, root, String
753:     self.class.new @path.sub(/^#{root}\/?/,'/'), @options.merge(opts)
754:   end

When given a path that matches the Route itself, a hash is returned with keys being parameters and values being the associated value gathered from the path.

[Source]

     # File maveric.rb, line 735
735:   def route path
736:     ::Maveric.log.debug "#{self.class}#route #{path.inspect} : #{self}"
737:     ::Maveric.type_check :path, path, String
738:     if self =~ path
739:       Hash[ *@params.zip($~.captures).flatten ].update(nil => self)
740:     end
741:   end

Private Instance methods

Builds a regex from path by parsing out fragments matching PARAM_MATCH and replacing them with either a corresponding symbol from the opts hash or the default regex.

[Source]

     # File maveric.rb, line 775
775:   def __compile path, opts
776:     ::Maveric.type_check :path, path, String
777:     ::Maveric.type_check :opts, opts, Hash
778:     params = []
779:     regex = path.gsub PARAM_MATCH do
780:       param = $1.to_sym
781:       raise ArgumentError, "Duplicated parameter in path."+
782:         " <#{param.inspect}>" if params.include? param
783:       params << param
784:       "(#{opts[param] || URI_CHAR+'+'})"
785:     end
786:     [regex, params]
787:   end

[Validate]