我是Ruby的新手。我正处于试图用Ruby编写东西的失败的阶段,就像我在其他语言中那样。
我正在尝试将一个方法添加到一个对象 - 一个简陋的数组,让我们说。不是所有数组,只是一个特定的数组。此方法必须能够访问外部作用域中的变量。
我的理解是我可以使用def
向对象添加方法,但该方法无法访问外部作用域中的变量。为此,我需要使用lambda
或Proc.new
,但我无法看到我如何将lambda / proc作为属性附加到数组中。
在JavaScript中,这很简单,正如这个愚蠢的例子所示:
var x = 3
var array = [1, 2, 3, 4]
array.multiply_by_x = function() {
var i = this.length
while (i--) {
this[i] *= x
}
}
在Ruby中是否有类似上述内容?
答案 0 :(得分:4)
您不能在此处使用def关键字来定义方法,因为它将引入另一个范围。 如果要仅为特定对象定义方法,则必须在单例类中定义它。
x = 3
array = [1, 2, 3, 4]
array.define_singleton_method(:multiply_by_x) do
self.map!{|e| e * x }
end
但是如果你正在使用Ruby 1.8.x,你必须这样做:
(class << array; self; end).send(:define_method, :multiply_by_x) do
self.map!{|e| e * x }
end
注意:这与此问题无关,但如果您想查看different ways to define singleton methods.
答案 1 :(得分:1)
Monkey-patching Array
会执行此操作,但它会为Array
的所有实例执行此操作。
class Array
def multiply_by(x)
self.map! {|n|
n * x
}
end
end
如果你想任意地将方法修补到现有对象上,我认为这不可能。
您可以做的一件事是使用Hash
和lambda
:
x = 3
hash = {:array => [1,2,3]}
hash[:multiply_by] = lambda {
hash[:array].map! {|num|
num * x
}
}
然后你就像这样调用multiply_by
lambda:
hash[:multiply_by].call
答案 2 :(得分:0)
我宁愿这样做:
ary = [1, 2, 3, 4]
def ary.multyply_by(x)
self.map! {|e| e * x}
end
p ary.multyply_by 10
作为旁注,使用函数参数比使用高范围变量要好得多。范围是避免冲突的一种方式,而不是障碍。