Class: FunctionChain::PullChain
- Defined in:
- lib/function_chain/pull_chain.rb
Overview
PullChain
PullChain is object as represent method call chain. Can inner object’s method call of object.
Chain is object, so can call later.
Supported call chain type is like a
account.user.name
Unsupported call chain type is like a
filter3(filter2(filter1(value)))
(RelayChain to support such type.)
Example
Account = Struct.new(:user)
User = Struct.new(:name)
account = Account.new(User.new("Louis"))
chain = PullChain.new(account, :user, :name, :upcase)
chain.call # => LOUIS
similar.
# Strings separated by a slash
PullChain.new(account, "user/name/upcase").call
# use << operator.
chain = PullChain.new(account)
chain << :user << :name << :upcase
chain.call
# use add method.
chain.add(:user).add(:name).add(:upcase).call
# use add_all method.
chain.add_all(:user, :name, :upcase).call
can exist nil value on the way, like a following case.
user.name = nil
chain.call # => nil
insert, insert_all method is insert_all method to chain. delete_at method is delete method from chain. clear method is delete all method from chain.
Require arguments on method
Following example is required two arguments.
class Foo
def say(speaker, )
puts "#{speaker} said '#{}'"
end
end
Solution1:Array, format is [Symbol, [*Args]].
chain = PullChain.new(Foo.new) << [:say, ["Andres", "Hello"]]
chain.call => Andres said 'Hello'
Solution2:String
chain = PullChain.new(foo) << "say('John', 'Goodbye')"
chain.call => John said 'Goodbye'
Require block on method
[1,2,3,4,5].inject(3) { |sum, n| sum + n } # => 18
Solution1:Array, format is [Symbol, [*Args, Proc]].
chain = PullChain.new([1,2,3,4,5])
chain << [:inject, [3, lambda { |sum, n| sum + n }]]
chain.call # => 18
Solution2:String
chain = PullChain.new([1,2,3,4,5])
chain << "inject(3) { |sum, n| sum + n }"
chain.call # => 18
Use result on chain
Like a following example, can use result on chain. Example1:String
Foo = Struct.new(:bar)
Bar = Struct.new(:baz) {
def speaker ; "Julian" end
}
class Baz
def say(speaker, ) puts "#{speaker} said '#{}'" end
end
foo = Foo.new(Bar.new(Baz.new))
# can use bar instance in backward!
chain = PullChain.new(foo) << "bar/baz/say(bar.speaker, 'Good!')"
chain.call # => Julian said 'Good!'
furthermore, can use variable name assigned.
# @b is bar instance alias.
chain = PullChain.new(foo) << "@b = bar/baz/say(b.speaker, 'Cool')"
chain.call # => Julian said 'Cool'
Example2:Array can access result by Proc.
chain = PullChain.new(foo) << :bar << :baz
chain << [:say, Proc.new { next .speaker, "Oh" }]
chain.call # => Julian said 'Oh'
case of use a lambda, can use result access object explicit.
chain = PullChain.new(foo) << :bar << :baz
arg_reader = lambda { |accessor| next accessor..speaker, "Oh" }
chain << [:say, arg_reader]
chain.call # => Julian said 'Oh'
etc
How to use slash in strings separated by a slash. like following, please escaped by backslash.
chain = PullChain.new("AC") << "concat '\\/DC'"
chain.call # => AC/DC
Use return_nil_at_error= method, then can ignore error.
chain = PullChain.new("Test") << :xxx
begin
chain.call # => undefined method `xxx'
rescue
end
chain.return_nil_at_error = true
chain.call # => nil
Note:use operator in string type chain
table = {name: %w(Bill Scott Paul)}
PullChain.new(table, "[:name]").call # NG
PullChain.new(table, "self[:name]").call # OK
# Array type chain
PullChain.new(table, [:[], [:name]]).call # OK
following is also the same.
# <<operator of String
PullChain.new("Led", "self << ' Zeppelin'").call
# []operator of Array
PullChain.new(%w(Donald Walter), "self[1]").call
Some classes, such Fixnum and Bignum not supported.
# NG
PullChain.new(999999999999999, "self % 2").call
Instance Attribute Summary collapse
-
#return_nil_at_error ⇒ Object
writeonly
Sets the attribute return_nil_at_error.
Instance Method Summary collapse
-
#call ⇒ Object
Call to all added method.
-
#initialize(receiver, *functions) ⇒ PullChain
constructor
Initialize chain.
- #return_nil_at_error? ⇒ Boolean
Methods inherited from BaseChain
#add, #add_all, #clear, #delete_at, #insert, #insert_all, #to_s
Constructor Details
#initialize(receiver, *functions) ⇒ PullChain
Initialize chain
initialize(receiver, *functions) receiver: starting point of method call. *functions: more than one symbol, string, array.
150 151 152 153 154 |
# File 'lib/function_chain/pull_chain.rb', line 150 def initialize(receiver, *functions) @start_receiver = receiver @return_nil_at_error = false add_all(*functions) end |
Instance Attribute Details
#return_nil_at_error=(value) ⇒ Object (writeonly)
Sets the attribute return_nil_at_error
143 144 145 |
# File 'lib/function_chain/pull_chain.rb', line 143 def return_nil_at_error=(value) @return_nil_at_error = value end |
Instance Method Details
#call ⇒ Object
Call to all added method.
157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/function_chain/pull_chain.rb', line 157 def call @result_accessor = Object.new begin chain_elements.reduce(@start_receiver) do |receiver, chain_element| break receiver if receiver.nil? chain_element.call receiver end rescue raise unless return_nil_at_error? end end |
#return_nil_at_error? ⇒ Boolean
169 170 171 |
# File 'lib/function_chain/pull_chain.rb', line 169 def return_nil_at_error? @return_nil_at_error end |