参数是通过引用还是值传递给方法的?
当您将参数传递给 Ruby 中的方法时,任何人都可以扩展、更正或验证我认为发生的情况吗?这些观点有错吗?我缺少任何碎片吗?
- Ruby 中的一切都是对象。
- 变量是对对象的引用
- (将变量传递到方法中时):捕获变量的方法中的参数是该方法的局部变量。参数(局部变量)现在也具有对同一对象的引用。
- 我可以(就地)更改对象,并且当退出方法作用域时,此更改将保持。在方法范围之外引用该对象的任何变量都将反映该对象已被更改。
- 对该参数(局部变量)的新赋值不会更改原始对象,因此当方法离开作用域时对其的任何引用都将保持不变。
- 如果我将变量传递到引用整数的方法中,那么一旦该方法退出,我实际上就无法让该变量引用新的整数。
有没有办法让一种方法将整数作为其参数之一,执行一些操作,并且可能作为副作用更改值,并在方法退出后反映该更改。也许我只是不考虑“Ruby 方式”。
Can anyone expand upon, correct, or verify what I feel is happening when you pass arguments to a method in Ruby. Are any of these points wrong? Am I missing any pieces?
- Everything in Ruby is an object.
- Variables are references to objects
- (When passing in a variable into a method): The parameter in the method that catches the variable is a local variable to that method. The parameter (local variable) now also has a reference to the same object.
- I could alter the object (in place) and this alteration will hold when the method scope is exited. Any variables referencing this object outside the method scope will reflect that the object has been altered.
- A new assignment to that parameter (local variable) does not change the original object, thus any references to it when the method leaves scope will remain unchanged.
- If I am passing a variable into the method that references an Integer there is effectively no way that once that method exits I could have that variable referencing a new Integer.
Is there any way to have a method that takes as one of its parameters an Integer, does some stuff, and maybe as a side effect changes the value, having that change reflected once the method exits. Maybe I am just not thinking "the Ruby way".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
足够接近。
不。变量“命名”一个对象:当一个变量被求值时,它的求值结果是它当前“命名”的对象。在内部,这是通过“存储指针”(或等效机制)到对象来完成的。 (尽管实现并不需要总是使用指针:例如,在 Ruby MRI 中,Fixnum 值实际上存在而没有真实的对象。)
不,见上文。但是,这两个变量现在命名(或“计算为”)同一个对象。使用 Call-by-Value 在内部传递参数 - - 也就是说,在内部,传递指向对象的指针 - 尽管 Ruby 有 Call-by-Object-Sharing 语义,这是我尝试推广的一个术语,因为我发现它简洁地描述了行为。
是的,物体就是它本身。如果您改变那个对象,那么您就在各处改变那个对象。但请注意:没有任何变量发生变化。内部和外部变量仍然命名(或“评估”)相同的对象。
正确的。如果您为您创建的局部变量分配不同的值,则局部变量将命名为不同的对象。 Ruby 不是Call-by-Reference,因此变量调用上下文不会改变。
变量永远不会被传递。 变量被评估为其命名的对象,并且这些对象被传递。无论如何,我们知道:
因此:
永远不能改变
x
的名字,甚至也不能改变对象x
名字的内容(因为它是,嗯,不可变的)。即使x
命名的对象是可变的,该方法也不能更改对象x
命名的内容:它只能变异由x
计算得到的对象。快乐编码。
现在,在我的书中,Ruby Way 将使用更好的返回值来包含所有新状态,并让调用者将其放在需要的地方:-)
当然,可变对象(包括简单数组)也是一种选择,但这很糟糕。而且,如果有足够多的州一起旅行,它可能是一个单独类别的候选者。
作为结束语:Ruby 支持闭包的概念,因此可以以词法范围的方式:(
这是针对简单的 lambda 进行展示的,但可以设计/制作一种方法来工作原理类似:在所有像这样的愚蠢的反例中,外部变量本身需要知道,但是,因为 lambda/方法无法将外部变量名称设置为新对象否则。)
Close enough.
No. A variable "names" an object: when a variable is evaluated, it evaluates to the object that it currently "names". Internally this is done by "storing a pointer" (or equivalent mechanism) to an object. (Although an implementation does not need to always use pointers: in Ruby MRI, for instance, Fixnum values actually exist without a real object.)
No. See above. However, both variables now name (or "evaluate to") the same object. The parameters are passed internally using Call-by-Value -- that is, internally, the pointers to the objects are passed -- although Ruby has Call-by-Object-Sharing semantics, which is a term I try to promote as I find it succinctly describes the behavior.
Yes, an object is itself. If you mutate that object, you mutate that object everywhere. But note: none of the variables are changed. Both the inside and the outside variables will still name (or "evaluate to") the same object.
Correct. If you assign a different value to the local variable you make it, the local variable, name a different object. Ruby is not Call-by-Reference so the variable in the calling context is not altered.
Variables are never passed. Variables are evaluated to the objects they name and those objects are passed. Anyway, we know that:
Thus:
can never change what
x
names, nor can it even change the contents of the objectx
names (because it's, well, immutable). Even if the object thatx
named was mutable, the method could not have changed what objectx
names: it could only have mutated the object that resulted from the evaluation ofx
.Happy coding.
Now, The Ruby Way -- in my book -- would be to use a better return value that compassed all the new state, and let the caller put it where it needs to go :-)
Of course, mutable objects (including simple arrays) are also an option, but that's ick. And, if there is enough state that travels together, it might be a candidate for a separate class.
As a closing note: Ruby supports a concept of closures, so it is possible in a lexically-scoped manner:
(This was shown for a simple lambda, but it is possible to design/craft a method to work similarly: in all the silly counter-examples like this, the outside variable itself needs to be known, however, as there is no way for the lambda/method of make an outside variable name a new object otherwise.)