0
class Test
  def initialize
    @foo = 1
    @bar = 1
  end
  def change(a, b) 
    a += 1
    b -= 1   
  end 
  def print
    change(@foo,@bar)
    puts "#{@foo},#{@bar}"
  end
end

由于变量foobar可能在这个类中多次一起修改,我想知道我是否可以使用一种方法来完成这项工作。我想在仍然进入上述代码2,0的同时打印方法。有没有一种简单的方法可以在 Ruby 中编写这样的方法?print1,1

4

3 回答 3

0

Ruby 实际上可以做到这一点,但它并没有你想象的那么清楚。在 Ruby 中,所有变量都只是对对象的引用。所以:

2.0.0p0 :001 > def m(a)
2.0.0p0 :002?>   a << 1
2.0.0p0 :003?>   a
2.0.0p0 :004?> end
 => nil
2.0.0p0 :005 > a = [3,2]
 => [3, 2]
2.0.0p0 :006 > m(a)
 => [3, 2, 1]
2.0.0p0 :007 > a
 => [3, 2, 1]

但是,整数是不可变的。所以,你不能对整数变量做同样的事情。你看,+=、-=、*= 等都是真的var = var +/-/* rhs。这只会修改存储在局部变量中的引用,而不是在传递的变量中。你真的有两个选择:

  1. 使用可变对象:使用 Hash、Array 等——并确保使用破坏性操作,如<<,flatten!等。
  2. 将 Integer 包装在一个简单的可变对象中:编写一个可变包装类,让您可以做到这一点。
于 2013-03-10T14:23:39.617 回答
0

这样的事情有用吗?

class Test
  def initialize
    @foo = 1
    @bar = 1
  end
  def change(a, b) 
    a += 1
    b -= 1
    [a, b]   
  end 
  def print
    @foo, @bar = change(@foo,@bar)
    puts "#{@foo},#{@bar}"
  end
end

你可以在 Ruby 中做这样的事情,但它更高级,因为没有内置按引用传递。

这将导致更难理解源代码。有意想不到的副作用。

于 2013-03-10T12:31:33.890 回答
0

整数是 Ruby 中的不可变对象,因此您不能那样修改它们。a += 1只是用新值重新分配局部变量a,它不会修改原始对象(1)。

为了实现你想要的(虽然你还没有真正解释你想要什么),你有几种可能:

  • 在对象中包装整数(对于这样一个简单的例子来说很麻烦)

  • 使用可变对象而不是整数,例如哈希。

例如:

class Test
  def initialize
    @foo_bar = { foo: 1, bar: 1 }
  end
  def change(a, b) 
    @foo_bar[a] += 1
    @foo_bar[b] -= 1
  end 
  def print
    change(:foo,:bar)
    puts "#{@foo_bar[:foo]},#{@foo_bar[:bar]}"
  end
end

另外,请注意:很少需要将对象的实例变量作为参数传递给同一对象的方法(change(@foo,@bar)在您的示例中)。实例变量用于保持对象的内部状态。

于 2013-03-10T12:38:59.450 回答