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