2

我是红宝石的新手。我正处于尝试用 Ruby 写东西的阶段,就像我用其他语言一样。

我正在尝试向一个对象添加一个方法——比如说,一个不起眼的数组。并非针对所有阵列,仅针对一个特定阵列。此方法必须有权访问外部范围内的变量。

我的理解是,我可以使用def向对象添加方法,但该方法无法访问外部范围内的变量。为此,我需要使用lambdaor 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 中是否有可能与上述类似的东西?

4

3 回答 3

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

注意:它与这个问题无关,但如果您想查看定义单例方法的不同方法。

于 2011-10-11T05:32:33.303 回答
1

Monkey-patchingArray可以做到这一点,但它会为Array.

class Array
  def multiply_by(x)
     self.map! {|n|
        n * x
     }
  end
end

如果您想任意将方法修补到现有对象上,我认为这是不可能的。

您可以做的一件事是将 aHash与 a 一起使用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
于 2011-10-11T04:13:31.077 回答
0

我宁愿这样做:

ary = [1, 2, 3, 4]

def ary.multyply_by(x)
  self.map! {|e| e * x}
end

p ary.multyply_by 10

作为旁注,使用函数参数比使用高度范围的变量要好得多。范围是避免冲突的一种方式,而不是障碍。

于 2011-10-11T07:15:07.927 回答