Ruby 动态方法链?

Ruby 动态方法链?,ruby,Ruby,如何调用对象上方法名称的嵌套哈希 例如,给定以下哈希: hash = {:a => {:b => {:c => :d}}} 我想创建一个方法,在给定上述散列的情况下,该方法执行以下等效操作: object.send(:a).send(:b).send(:c).send(:d) 其思想是我需要从未知关联(此方法未知,但程序员已知)获取特定属性 我希望能够指定一个方法链,以嵌套哈希的形式检索该属性。例如: hash = {:manufacturer => {:addres

如何调用对象上方法名称的嵌套哈希

例如,给定以下哈希:

hash = {:a => {:b => {:c => :d}}}
我想创建一个方法,在给定上述散列的情况下,该方法执行以下等效操作:

object.send(:a).send(:b).send(:c).send(:d)
其思想是我需要从未知关联(此方法未知,但程序员已知)获取特定属性

我希望能够指定一个方法链,以嵌套哈希的形式检索该属性。例如:

hash = {:manufacturer => {:addresses => {:first => :postal_code}}}
car.execute_method_hash(hash)
=> 90210

没有预定义的方法,但您可以为此定义自己的方法:

class Object
  def send_chain(chain)
    k = chain.keys.first
    v = chain.fetch(k)
    r = send(k)
    if v.kind_of?(Hash)
      r.send_chain(v)
    else
      r.send(v)
    end
  end
end

class A
  def a
    B.new
  end
end

class B
  def b
    C.new
  end
end

class C
  def c
    D.new
  end
end

class D
  def d
    12345
  end
end

chain = { a: { b: { c: :d } } }
a = A.new
puts a.send_chain(chain)  # 12345

使用

测试时,我会使用数组而不是散列,因为散列允许不一致(如果(子)散列中有多个键怎么办?)

使用阵列时,以下操作有效:

# This is just a dummy class to allow introspection into what's happening
# Every method call returns self and puts the methods name.
class Thing
  def method_missing(m, *args, &block)
    puts m
    self
  end
end

# extend Object to introduce the call_methods method
class Object
  def call_methods(methods)
    methods.inject(self) do |obj, method|
      obj.send method
    end
  end
end

call_methods
中,我们在符号数组中使用
inject
,以便将每个符号发送到前一个send方法返回的方法执行结果。最后一次发送的结果由
inject

自动返回。有一种更简单的方法

class Object

  def your_method
    attributes = %w(thingy another.sub_thingy such.attribute.many.method.wow)
    object = Object.find(...)
    all_the_things << attributes.map{ |attr| object.send_chain(attr.split('.')) }
  end

  def send_chain(methods)
    methods.inject(self, :try)
  end

end
类对象
定义你的方法
attributes=%w(thingy另一个.sub_thingy如.attribute.many.method.wow)
object=object.find(…)

你所写的“下面的链条”并不是链条。这是一个散列。您的代码将按原样工作。问题还不清楚。这是RubyonRails的特别之处吗?您的最后一个示例不完整。什么是
汽车
?什么是
execute\u method\u hash
?是什么让它返回
90210
?这是没有帮助的。我想创建的方法是execute\u method\u hash。给定一个散列,该方法将遍历散列,然后根据前一个方法调用的结果调用每个方法。汽车只是属于制造商的物体的一个例子。执行此方法链将获得该制造商的第一个地址并返回其邮政编码,即90210
class Object

  def your_method
    attributes = %w(thingy another.sub_thingy such.attribute.many.method.wow)
    object = Object.find(...)
    all_the_things << attributes.map{ |attr| object.send_chain(attr.split('.')) }
  end

  def send_chain(methods)
    methods.inject(self, :try)
  end

end