sli*_*000 10 ruby pass-by-reference pass-by-value
当你将参数传递给Ruby中的方法时,任何人都可以扩展,纠正或验证我的感受.这些点中的任何一个都错了吗?我错过任何一件作品吗?
有没有办法让一个方法作为其参数之一的整数,做一些东西,也许作为副作用改变值,一旦方法退出反映了该变化.也许我只是不想"Ruby方式".
小智 21
Ruby中的所有东西都是一个对象.
足够近.
变量是对象的引用
否.变量"命名"一个对象:当一个变量被评估时,它会计算出它当前"命名"的对象.在内部,这是通过"存储指针"(或等效机制)到对象来完成的.(虽然实现不需要总是使用指针:例如,在Ruby MRI中,Fixnum值实际上没有真实对象.)
(将变量传入方法时):捕获变量的方法中的参数是该方法的局部变量.参数(局部变量)现在也具有对同一对象的引用.
不,见上文.但是,这两个变量现在都命名(或"评估为")同一个对象.参数在内部使用Call-by-Value传递- 也就是说,在内部传递指向对象的指针 - 尽管Ruby具有Call-by-Object-Sharing语义,这是我试图提升的术语,因为我发现它简洁地描述了这种行为.
我可以改变对象(就地),当退出方法范围时,这种改变将成立.在方法范围之外引用此对象的任何变量都将反映该对象已被更改.
是的,一个对象本身.如果您改变该对象,则会在任何地方改变该对象.但请注意:没有变量发生变化.内部和外部变量仍然会命名(或"评估")同一个对象.
对该参数(局部变量)的新赋值不会更改原始对象,因此当方法离开作用域时对它的任何引用都将保持不变.
正确.如果为您创建的局部变量分配不同的值,则局部变量将其命名为另一个对象.Ruby 不是 Call-by-Reference,因此调用上下文中的变量不会改变.
如果我将一个变量传递给引用Integer的方法,那么一旦该方法退出,我实际上没有办法让该变量引用一个新的Integer?
变量永远不会传递.变量将根据它们命名的对象进行计算,并传递这些对象.无论如何,我们知道:
从而:
x = 1
y.foo(x)
Run Code Online (Sandbox Code Playgroud)
可从来没有改变什么x名字,也不能把它甚至改变对象的内容x的名称(因为它的,好了,不可变的).即使该对象x命名是可变的,该方法不可能改变什么对象x的名字:它只能有突变起因于评价对象x.
快乐的编码.
现在,Ruby Way - 在我的书中 - 将使用更好的返回值来包含所有新状态,并让调用者把它放在需要去的地方:-)
当然,可变对象(包括简单数组)也是一种选择,但那就是ick.而且,如果有足够的州一起旅行,它可能是一个单独的班级的候选人.
作为结束语:Ruby支持闭包的概念,因此可以以词法范围的方式:
x = 1; (lambda {|a| x = a}).call(2); x // => 2
Run Code Online (Sandbox Code Playgroud)
(这是针对一个简单的lambda显示的,但是可以设计/制作一个类似的方法:在所有这样的愚蠢反例中,外部变量本身需要知道,但是,因为没有办法lambda /方法使外部变量名称成为新对象.)