Class: Maveric::Route

Inherits:
Regexp
  • Object
show all
Defined in:
lib/maveric.rb

Overview

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.

Constant Summary collapse

URI_CHAR =

A negative class of URI delimiting and reserved characters.

'[^/?:,&#]'
PARAM_MATCH =

Standard pattern for finding parameters in provided paths.

%r~:(#{URI_CHAR}+):?~

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, opts = {}) ⇒ Route

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


681
682
683
684
685
686
687
688
689
690
691
692
693
694
# File 'lib/maveric.rb', line 681

def initialize path, opts={}
  ::Maveric.type_check :path, path, String
  ::Maveric.type_check :opts, opts, Hash

  @path = path.dup.freeze
  @options = opts.dup.freeze

  regex, @params = __compile path, opts
  @params.freeze
  super %r~^#{regex}$~iu
  freeze

  ::Maveric.log.debug self.inspect
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.



696
697
698
# File 'lib/maveric.rb', line 696

def options
  @options
end

#paramsObject (readonly)

Returns the value of attribute params.



696
697
698
# File 'lib/maveric.rb', line 696

def params
  @params
end

#pathObject (readonly)

Returns the value of attribute path.



696
697
698
# File 'lib/maveric.rb', line 696

def path
  @path
end

Instance Method Details

#build(arg) ⇒ Object

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?



705
706
707
708
709
710
711
# File 'lib/maveric.rb', line 705

def build arg
  ::Maveric.log.debug "#{self.class}#build #{arg.inspect} : #{@params}"
  ::Maveric.type_check :arg, arg, Hash
  if @params.sort == arg.keys.sort
    path = arg.inject(@path){|r,(k,v)| r.sub /:#{k}:?/, v }
  end
end

#inspectObject

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



741
742
743
744
745
746
747
748
749
# File 'lib/maveric.rb', line 741

def inspect
  "#<%s:0x%x %s %s %s>" % [
    self.class,
    [object_id<<1].pack('i').unpack('I')[0],
    super,
    @params.inspect,
    @path.inspect
  ]
end

#reroot(root, opts = {}) ⇒ Object

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


733
734
735
736
# File 'lib/maveric.rb', line 733

def reroot root, opts={}
  ::Maveric.type_check :root, root, String
  self.class.new @path.sub(/^#{root}\/?/,'/'), @options.merge(opts)
end

#route(path) ⇒ Object

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.



717
718
719
720
721
722
723
# File 'lib/maveric.rb', line 717

def route path
  ::Maveric.log.debug "#{self.class}#route #{path.inspect} : #{self}"
  ::Maveric.type_check :path, path, String
  if self =~ path
    Hash[ *@params.zip($~.captures).flatten ].update(nil => self)
  end
end