Understanding passing by value vs. reference in this Ruby example
Understanding passing by value vs. reference in this Ruby example
After reading Is ruby pass by reference or value? I have learned a lot, but I am left with more questions than I had before reading it (which I suppose is good).
Consider the following example
def foo(bar) bar = 'reference' end baz = 'value' foo(baz) puts "Ruby is pass-by-#{baz}" Output Ruby is pass-by-value
Here is my attempt to dissect how this works:
First, in the global scope baz has the value value.
Now foo takes a parameter, whatever you pass into it, is on a local level.
Therefore when we pass baz in, there is ANOTHER baz that is equal to reference but this is on the local level, as a result, when we puts this on a global level it prints value.
Now consider another example
def foo(bar) bar.replace 'reference' end baz = 'value' foo(baz) puts "Ruby is pass-by-#{baz}" Output
Ruby is pass-by-reference
If what I said above is true, does the .replace method here change the global baz? Am I interpreting this correctly? Please feel free to point out any mistakes in my attempts, I have no clue if im on the right track.
Thanks!
EDIT
More Magic
def my_foo(a_hash) a_hash["test"]="reference" end; hash = {"test"=>"value"} my_foo(hash) puts "Ruby is pass-by-#{hash["test"]}" Answer by michau for Understanding passing by value vs. reference in this Ruby example
It actually has nothing to do with passing parameters to methods. I extracted important parts from your examples:
baz = 'value' bar = baz bar = 'reference' puts baz bar = baz bar.replace 'reference' puts baz You may think of variables as pointers. When you use =, you make a variable point to something different, and the original value remains unchanged, and can be accessed through other variables that point at it. But when you use replace, you change the content of the string the variable points at.
Answer by Dave Schweisguth for Understanding passing by value vs. reference in this Ruby example
Ruby is pass-by-value, but the values are references to objects.
In your first experiment, baz is a reference to the string "value". bar is initialized to a copy of baz (that is, a copy of the reference) when you call foo. You then overwrite bar with a reference to the string "reference". Since bar is a copy, overwriting it doesn't change baz.
In your second experiment, again, baz is a reference to the string "value" and bar is initialized to a copy of baz when you call foo. This time you don't overwrite bar, but call a method on it. Although bar is a copy of baz, they refer to the same object (the string "value"). Calling the method changes the state of that object. You then call to_s on baz (indirectly, by substituting it into "Ruby is pass-by-#{baz}"), and to_s returns the new state.
Your third experiment is a lot like the second. In the method, you change the state of the object referred to by the copy of the reference, then, outside the method, you read the new state back through the original reference.
Answer by Maxim Pontyushenko for Understanding passing by value vs. reference in this Ruby example
In first case you use bar = 'reference' which creates new object. In second one .replace changes the object you apply it to. You can ensure this by .object_id method. For example:
def foo_eql(bar) bar = 'reference' puts bar.object_id bar end def foo_replace(bar) bar.replace 'reference' puts bar.object_id bar end baz = 'value' puts baz.object_id #Here you will get original baz object_id res1 = foo_eql(baz) #Here you will get printed new object_id res2 = foo_replace(baz) #Here you will get printed original baz object_id puts "foo_eql: Ruby is pass-by-#{res1}" => foo_eql: Ruby is pass-by-reference puts "foo_replace: Ruby is pass-by-#{res2}" => foo_replace: Ruby is pass-by-reference So there is no magic at all. In your example with hashes you do not create new Hash object but modify existing one. But you can create new one with method like this:
def my_foo(a_hash) a_hash = a_hash.merge({"test" => "reference"}) end my_foo(hash) puts "Ruby is pass-by-#{hash["test"]}" Basically you pass the reference to an object in "value" way. For better understanding check this post and comments to it.
Answer by Fran Martinez for Understanding passing by value vs. reference in this Ruby example
Very interesting thing.
Play with the object_ids, you will see what ruby is doing bellow the scenes:
def foo(bar) puts bar.object_id bar = 'reference' puts bar.object_id end baz = 'value' puts baz.object_id foo(baz) Output
> baz = 'value' => "value" > puts baz.object_id 70241392845040 > foo(baz) 70241392845040 70241392866940 After the local assign bar = 'reference', the local variable bar will reference another object, so it won't change the original one.
It seems that in some cases it will make a dup of your object.
Answer by maicher for Understanding passing by value vs. reference in this Ruby example
Maybe this will help to understand it:
x = 'ab' x.object_id => 70287848748000 # a place in memory x = 'cd' x.object_id => 70287848695760 # other place in memory (other object) x.replace('xy') x.object_id => 70287848695760 # the same place in memory (the same object) Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:
Post a Comment