开发者

Ruby: How to chain multiple method calls together with "send"

There has to be a built in way of doin开发者_运维技巧g this, right?

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


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

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


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.


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜