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
由于变量foo
和bar
可能在这个类中被多次修改,我想知道我是否可以使用一种方法来完成这项工作。我想在方法2,0
中打印print
,而我仍然在上面的代码中获得1,1
。有没有一种简单的方法在Ruby中编写这样的方法?
答案 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
。这仅修改存储在局部变量中的引用,而不是修改传递的变量。你真的有两个选择:
<<
,flatten!
等破坏性操作。