Ruby 中的一切都是对象。
足够接近。
变量是对对象的引用
没有。一个变量“命名”一个对象:当一个变量被计算时,它计算为它当前“命名”的对象。在内部,这是通过“存储指针”(或等效机制)到对象来完成的。 (虽然实现不需要总是使用指针:例如,在 Ruby MRI 中,Fixnum 值实际上存在 一个真实的对象。)
(将变量传递给方法时):方法中捕获变量的参数是该方法的局部变量。参数(局部变量)现在也引用了同一个对象。
没有。往上看。但是,这两个变量现在命名(或“评估”)同一个对象。 内部使用Call-by-Value传递参数——也就是说,内部传递指向对象的指针——尽管Ruby有Call-by-Object-Sharing语义,这是一个我尝试推广的术语,因为我发现它简洁地描述了行为。
我可以(就地)更改对象,并且当退出方法范围时,此更改将保持不变。在方法范围之外引用此对象的任何变量都将反映该对象已被更改。
是的,一个对象就是它自己。如果你改变那个对象,你就会在任何地方改变那个对象。但请注意:没有任何变量被更改。内部和外部变量都将仍然命名(或“评估”)相同的对象。
对该参数(局部变量)的新赋值不会改变原始对象,因此当方法离开作用域时对它的任何引用都将保持不变。
正确。如果您为创建它的局部变量(局部变量)分配不同的值,则命名不同的对象。 Ruby 不是 Call-by-Reference,因此调用上下文中的变量不会改变。
如果我将变量传递给引用 Integer 的方法,那么一旦该方法退出,我就无法让该变量引用新的 Integer?
变量从不传递。 变量被评估为它们命名的对象并传递这些对象。无论如何,我们知道:
- Ruby 不是 Call-by-Reference 和;
- 整数(Fixnums)是不可变的
因此:
x = 1
y.foo(x)
不能永远更改x 的名称,甚至不能更改对象x 名称的内容(因为它是不可变的)。即使x 命名的对象是可变的,该方法不可能 改变what 对象x 的名称:它只能变异 评估x 产生的对象。
编码愉快。
现在,Ruby 方式——在我的书中——将使用一个更好的返回值来包含 all 新状态,并让调用者将它放在需要去的地方:- )
当然,可变对象(包括简单数组)也是一种选择,但这是ick。而且,如果有足够多的状态可以一起旅行,它可能是一个单独的类的候选者。
作为结束语:Ruby 支持闭包的概念,因此可以以词法范围的方式:
x = 1; (lambda {|a| x = a}).call(2); x // => 2
(这是为一个简单的 lambda 显示的,但可以设计/制作一个类似的方法:在像这样的所有愚蠢的反例中,outside 变量本身需要是但是,已知,因为 lambda/方法无法将外部变量名称设为新对象。)