如何在传递的块中引用Object的参数?

时间:2017-07-26 23:11:56

标签: ruby oop metaprogramming

我正在尝试引用与其一起传递的块内的Object的一个参数。

def command(attributes = {}, &block)
    yield
end

command(attr_1: 'Open Mike Night', 
    attr_2: 2033392,
    attr_3: [9.29, 10.08, 12.32]) do |event|

    event.message.delete

    puts "#{self.attributes[:attr_1]}" # <-- That didn't work.

end

这样的事情是否可能,如果是这样,我将如何去做呢?我该怎么看?

2 个答案:

答案 0 :(得分:0)

在我的头顶,你可以做这样的事情。警告我不知道这是否适合生产代码。

此代码通过迭代参数哈希的键为每个键创建实例变量。然后,当我们调用command时,我们可以使用相应的instance_variable来引用块中的每个键的值:

def command(attributes = {}, &block)
  attributes.each_key { |key| 
    instance_variable_set("@#{key}",attributes[key])
  }
  yield
end

command(attr_1: 'Open Mike Night',
        attr_2: 2033392,
        attr_3: [9.29, 10.08, 12.32]) do |event|

  puts "#{@attr_1}"
end

打印:

Open Mike Night

答案 1 :(得分:0)

将它们收集到块中:)

def command(attributes = {})
  yield self, attributes
end

attributes = { attr_1: 'Open Mike Night', attr_2: 2033392, attr_3: [9.29, 10.08, 12.32] }

command(attributes) do |obj, attrs|
  p "#{obj.object_id}, #{attrs[:attr_1]}"
end 
# => "70309890142840, Open Mike Night"

方法范围内可用的任何方法,常量或变量都可以作为yield的参数给出,作为块变量发送到块中。然后你可以随心所欲地做到这一点。在这种情况下,attrs也是一个完全可选的变量,如果没有它,该块将是有效的。

command(attributes) { |obj| p obj.object_id } # => 70309890142840

P.S。如果您使用&block,则方法签名中不需要yield。你也没有在你的问题中给yield一个参数,而是将一个|event|变量传递给了一个nil块。所以我在上面的例子中就把它留了下来。