参数是通过引用还是值传递给方法的?

发布于 2024-12-25 07:51:02 字数 455 浏览 4 评论 0原文

当您将参数传递给 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吃颗糖壮壮胆 2025-01-01 07:51:02

Ruby 中的一切都是对象。

足够接近。

变量是对象的引用

不。变量“命名”一个对象:当一个变量被求值时,它的求值结果是它当前“命名”的对象。在内部,这是通过“存储指针”(或等效机制)到对象来完成的。 (尽管实现并不需要总是使用指针:例如,在 Ruby MRI 中,Fixnum 值实际上存在没有真实的对象。)

(将变量传入方法时):捕获该变量的方法中的参数是该方法的局部变量。参数(局部变量)现在也具有对同一对象的引用。

不,见上文。但是,这两个变量现在命名(或“计算为”)同一个对象。使用 Call-by-Value内部传递参数 - - 也就是说,在内部,传递指向对象的指针 - 尽管 Ruby 有 Call-by-Object-Sharing 语义,这是我尝试推广的一个术语,因为我发现它简洁地描述了行为。

我可以(就地)更改对象,并且当退出方法作用域时,此更改将保持。在方法范围之外引用此对象的任何变量都将反映该对象已被更改。

是的,物体就是它本身。如果您改变那个对象,那么您就在各处改变那个对象。但请注意:没有任何变量发生变化。内部和外部变量仍然命名(或“评估”)相同的对象

对该参数(局部变量)的新赋值不会更改原始对象,因此当方法离开作用域时对其的任何引用都将保持不变。

正确的。如果您为您创建的局部变量分配不同的值,则局部变量将命名为不同的对象。 Ruby 不是Call-by-Reference,因此变量调用上下文不会改变。

如果我将一个变量传递到引用整数的方法中,那么一旦该方法退出,我就不可能让该变量引用新的整数吗?

变量永远不会被传递。 变量被评估为其命名的对象,并且这些对象被传递。无论如何,我们知道:

  1. Ruby 不是按引用调用;并且;
  2. 整数(Fixnums)是不可变的

因此:

x = 1
y.foo(x)

永远不能改变x的名字,甚至也不能改变对象x名字的内容(因为它是,嗯,不可变的)。即使 x 命名的对象是可变的,该方法也不能更改对象 x 命名的内容:它只能变异x计算得到的对象。

快乐编码。


现在,在我的书中,Ruby Way 将使用更好的返回值来包含所有新状态,并让调用者将其放在需要的地方:-)

当然,可变对象(包括简单数组)也是一种选择,但这很糟糕。而且,如果有足够多的州一起旅行,它可能是一个单独类别的候选者。


作为结束语:Ruby 支持闭包的概念,因此可以以词法范围的方式:(

x = 1; (lamb­da {|a| x = a}).c­all(2); x  // => 2

这是针对简单的 lambda 进行展示的,但可以设计/制作一种方法来工作原理类似:在所有像这样的愚蠢的反例中,外部变量本身需要知道,但是,因为 lambda/方法无法将外部变量名称设置为新对象否则。)

Everything in Ruby is an object.

Close enough.

Variables are references to objects

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.)

(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.

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.

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.

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.

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.

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.

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?

Variables are never passed. Variables are evaluated to the objects they name and those objects are passed. Anyway, we know that:

  1. Ruby is not Call-by-Reference and;
  2. Integers (Fixnums) are immutable

Thus:

x = 1
y.foo(x)

can never change what x names, nor can it even change the contents of the object x names (because it's, well, immutable). Even if the object that x named was mutable, the method could not have changed what object x names: it could only have mutated the object that resulted from the evaluation of x.

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:

x = 1; (lamb­da {|a| x = a}).c­all(2); x  // => 2

(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.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文