Class: PathTo::WithParams

Inherits:
Object
  • Object
show all
Defined in:
lib/path-to/with_params.rb

Overview

Chaining parameter collection. Example:

p = WithParams.new.foo(:bar => "baz").fee[:fi => "fo"]  #=> <WithParams>
p.service                                               #=> :fee
p.params                                                #=> {:bar => "baz", :fi => "fo"}

Direct Known Subclasses

Application, DescribedRoutes::Application, Path

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent = nil, service = nil, params = {}) ⇒ WithParams

Initialize a new WithParams object. Parameters:

parent

Value for the parent attribute

service

Value for the service attribute

params

Value for the params attribute



26
27
28
# File 'lib/path-to/with_params.rb', line 26

def initialize(parent = nil, service = nil, params = {})
  @parent, @service, @params = parent, service, params || {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

Tries to respond to a missing method. We can do so if

  1. any args are hashes (merged to make a params hash), and

  2. #child_class_for returns a class or other factory object capable of creating a new child instance

In all other cases and in the case of error we invoke super in the hope of avoiding any hard-to-debug behaviour!



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/path-to/with_params.rb', line 78

def method_missing(method, *args)
  begin
    params = args.inject(Hash.new){|h, arg| h.merge(arg)}
    if (child_class = child_class_for(self, method, params))
      child(child_class, method, params)
    else
      super
    end
  rescue
    super
  end
end

Instance Attribute Details

#paramsObject (readonly)

Parameter hash



14
15
16
# File 'lib/path-to/with_params.rb', line 14

def params
  @params
end

#parentObject (readonly)

Parent object, presumably of type WithParams or descendant



11
12
13
# File 'lib/path-to/with_params.rb', line 11

def parent
  @parent
end

#serviceObject (readonly)

Service identifier, typically a method symbol intercepted in #method_missing by parent



17
18
19
# File 'lib/path-to/with_params.rb', line 17

def service
  @service
end

Instance Method Details

#[](params = {}) ⇒ Object

Creates a child instance with new params. Subclasses might override this to take values instead of hashes, as follows:

def [](value)
  super(:key => value)
end


51
52
53
# File 'lib/path-to/with_params.rb', line 51

def [](params = {})
  child(self.class, self.service, params)
end

#child(child_class = nil, service = nil, params = {}, *other_args) ⇒ Object

Creates a child instance. Parameters:

child_class

The class of the new instance, calls #child_class_for to determine this if none supplied

service

Value for the new instance’s service attribute, inherited from self (the parent) if none supplied

params

The new instance’s params, will be merged with self’s (the parent’s) params



37
38
39
40
41
42
# File 'lib/path-to/with_params.rb', line 37

def child(child_class = nil, service = nil, params = {}, *other_args)
  child_class ||= child_class_for(instance, service, params)
  service ||= self.service
  params = self.params.merge(params || {})
  child_class.new(self, service, params, *other_args)
end

#child_class_for(instance, service, params) ⇒ Object

Determines the class of a new child, given the parent instance, service and params



58
59
60
# File 'lib/path-to/with_params.rb', line 58

def child_class_for(instance, service, params)
  self.class
end

#complete_params_hash!(params_hash, names, values) ⇒ Object

Updates params_hash with positional parameters TODO: this is initially just for the DescribedRoutes implementation but there will be some refactoring to do



112
113
114
115
116
# File 'lib/path-to/with_params.rb', line 112

def complete_params_hash!(params_hash, names, values)#:nodoc:
  names[0...values.length].each_with_index do |k, i|
    params_hash[k] = values[i]
  end
end

#extract_params(args, params_hash = {}) ⇒ Object

Separates positional params from hash params TODO: this is initially just for the DescribedRoutes implementation but there will be some refactoring to do



95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/path-to/with_params.rb', line 95

def extract_params(args, params_hash={})#:nodoc:
  positional_params = []
  params_hash = params_hash.clone
  args.each do |arg|
    if arg.kind_of?(Hash)
      params_hash.merge!(arg)
    else
      positional_params << arg
    end
  end
  [positional_params, params_hash]
end

#respond_to?(method) ⇒ Boolean

Determines whether we can respond to method (missing or otherwise). We can respond to a missing method if #child_class_for returns a class for a new child.

Returns:

  • (Boolean)


66
67
68
# File 'lib/path-to/with_params.rb', line 66

def respond_to?(method)
  child_class_for(self, method, params) || super
end