void foo(int &x) -> Ruby? Passing integers by reference?

前端 未结 2 572
执念已碎
执念已碎 2021-01-15 17:15

as a way to spice up my C++ programming homework, I\'ve decided to instead of typing the C++ from the book onto my computer, instead reforming it in Ruby. Yes it\'s a bit si

相关标签:
2条回答
  • 2021-01-15 17:48

    In Ruby, arguments are passed by value. So the following method will never have any effect:

    def doesnt_swap(a, b)
      c = a
      a = b
      b = c
    end
    

    On the other hand, mosts objects are references, for examples strings, so you could write

    def swap_strings(a, b)
      c = a.dup
      a.replace(b)
      b.replace(c)
    end
    

    This would swap the string values of the two arguments.

    Integers are immediates, so there is no equivalent to replace; you can't write swap_integers.

    Anyways, in Ruby, you swap by writing a, b = b, a

    0 讨论(0)
  • 2021-01-15 17:54

    Ruby is strictly pass-by-value. Always. But sometimes those values are poointers.

    Here's a couple of links:

    • Java is Pass-by-Value, Dammit! (Scott "JavaDude" Stanchfield)
    • Parameter passing in Java (Jon Skeet)
    • Does Java pass by reference?
    • Java, pass-by-value, reference variables

    Note that while all of these say "Java", they should really say "Smalltalk and its descendants", which includes Java, Ruby and a ton of other languages.

    I think most of the confusion stems from two problems:

    1. Ruby passes references by value. But the word "reference" in that sentence is not the same as the word "reference" in "pass-by-reference". Maybe it is clearer when we disambiguate: let's replace "pass-by-reference" with "pass-by-variable" and "reference" with "pointer" (note that these are "good" well-behaved poointers, not the "bad" ones from C):
      • Fortran is pass-by-variable
      • Ruby is pass-by-value and the values it passes are mostly poointers
    2. The references (poointers) that Ruby passes point to mutable objects. Therefore, while you cannot change the reference, you can mutate the objects that the reference points to. The problem here is that Ruby (like most imperative object-oriented languages) confuses the concepts of identity, state and value. You can learn more about that problem and how to fix it here (Note that while they say "Clojure", the concepts that are presented are universal and could be applied equally well to OO):
      • Persistent Data Structures and Managed References - Clojure's Approach to Identity and State - Rich Hickey - QCon London 2009
      • Are We There Yet? - A deconstruction of object-oriented time - Rich Hickey - JVM Language Summit

    BTW: I deliberately misspelt "poointers" with an OO for object-orientation to make it clear that I am not talking about raw memory addresses, I am talking about opaque references to objects (and for obvious reasons I do not want to use the word "reference"; if you know a better word that is neither "pointer" nor "reference", I'd love to hear it).

    0 讨论(0)
提交回复
热议问题