Ruby: How to chain multiple method calls together with “send”

淺唱寂寞╮ 提交于 2020-04-07 14:28:39

问题


There has to be a built in way of doing this, right?

class Object
  def send_chain(arr)
    o=self
    arr.each{|a| o=o.send(a) }
    return o
  end
end

回答1:


I just ran across this and it really begs for inject:

def send_chain(arr)
  arr.inject(self) {|o, a| o.send(a) }
end



回答2:


No, there isn't a built in way to do this. What you did is simple and concise enough, not to mention dangerous. Be careful when using it.

On another thought, this can be extended to accept arguments as well:

class Object
  def send_chain(*args)
    o=self
    args.each do |arg|
      case arg
      when Symbol, String
        o = o.send arg # send single symbol or string without arguments
      when Array
        o = o.send *arg # smash the inner array into method name + arguments
      else
        raise ArgumentError
      end
    end
    return o
  end
end

this would let you pass a method name with its arguments in an array, like;

test = MyObject.new
test.send_chain :a_method, [:a_method_with_args, an_argument, another_argument], :another_method



回答3:


Building upon previous answers, in case you need to pass arguments to each method, you can use this:

def send_chain(arr)
  Array(arr).inject(self) { |o, a| o.send(*a) }
end

You can then use the method like this:

arr = [:to_i, [:+, 4], :to_s, [:*, 3]]
'1'.send_chain(arr) # => "555"

This method accepts single arguments as well.




回答4:


How about this versatile solution without polluting the Object class:

def chain_try(arr)
  [arr].flatten.inject(self_or_instance, :try)
end

or

def chain_send(arr)
  [arr].flatten.inject(self_or_instance, :send)
end

This way it can take a Symbol, a String or an Array with a mix of both even.🤔

example usage:

  • chain_send([:method1, 'method2', :method3])
  • chain_send(:one_method)
  • chain_send('one_method')



来源:https://stackoverflow.com/questions/4099409/ruby-how-to-chain-multiple-method-calls-together-with-send

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!