通过引用传递参数

时间:2013-03-10 12:17:14

标签: ruby

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中打印print,而我仍然在上面的代码中获得1,1。有没有一种简单的方法在Ruby中编写这样的方法?

3 个答案:

答案 0 :(得分: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中做这样的事情,但它更高级,因为没有内置的引用传递。

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

答案 1 :(得分: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))。实例变量用于保持对象的内部状态。

答案 2 :(得分: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. 使用可变对象:使用哈希,数组等内容 - 并确保使用<<flatten!等破坏性操作。
  2. 在一个简单的可变对象中包装一个Integer:编写一个可变的包装类,让你这样做。