Assignment and Parameter Passing

Most of the time, Ruby methods come with two access points—like the doors into and out of a room. The argument list provides the way in; the return value provides the way out. Modifications made to the input arguments do not affect the original data for the simple reason that when Ruby evaluates an expression, the result of that evaluation creates a new object, so any changes made to an argument affect only the new object, not the original piece of data. But there are exceptions to this rule, which I’ll show you now.

Let’s start by looking at the simplest case—a method that takes one value as a named parameter and returns another value:

in_out.rb

def change( x )
    x += 1
    return x
end

On the face of it, you might think you are dealing with a single object, x, here: The object x goes into the change method, and the same object x is returned. In fact, that is not the case. One object goes in (the argument), and a different object comes out (the return value). You can easily verify this using the object_id method to show a number that uniquely identifies each object in your program:

num = 10
puts( "num.object_id=#{num.object_id}" )
num = change( num )
puts( "num.object_id=#{num.object_id}" )

The identifier of the variable, num, is different before and after you call the change method. This shows that even though the variable name remains the same, the num object that is returned by the change method is different from the num object that was sent to it.

The method call itself has nothing to do with the change of the object. You can verify this by running method_call.rb. This simply passes the num object to the change method and returns it:

method_call.rb

def nochange( x )
   return x
end

In this case, the object_id is the same after num is returned as it was before num was sent to the method. In other words, the object that went into the method is the same object as the one that came out again. That leads to the inevitable conclusion that there is something about the assignment in the change method (x += 1) that caused the creation of a new object.

But assignment itself isn’t the whole explanation. If you simply assign a variable to itself, no new object is created:

assignment.rb

num = 10
num = num     # a new num object is not created

If you now display the object_id of the num variable, the number is the same before an after assignment, proving that this really is the same object. So, what if you assign to the object the same value that it already has?

num = 10
num = 10      # a new num object is not created

Once again, the object_id is unchanged after the assignment. This demonstrates that assignment alone does not necessarily create a new object. Now let’s try assigning a new value:

num = 10
num += 1      # this time a new num object is created

This time, if you display num.object_id before and after the assignment, you will see a different number—say 21 before and 23 after. The actual numbers are automatically determined by Ruby and may vary. The important thing to understand is that a different object ID indicates a different object. If the same variable returns a different object_id when a value is assigned to it, that means a new object has been created.

Most data items are treated as unique, so one string “hello” is considered to be different from another string “hello,” and one float 10.5 is considered to be different from another float 10.5. Thus, any string or float assignment will create a new object.

But when working with integers, only when the assignment value is different from the previous value is a new object created. You can do all kinds of complicated operations on the right side of the assignment, but if the yielded value is the same as the original value, no new object is created.

num = 11
puts( "num.object_id=#{num.object_id}" )
num = (((num + 1 - 1) * 100) / 100)
puts( "num.object_id=#{num.object_id}" )

In the previous code, the first assignment creates a new num object with the integer value 11. Even though the result of a fairly complex expression is used in the next assignment, this still has the value 11. Since the value of num is not changed, no new objects are created, and its object_id remains the same:

num.object_id=23
num.object_id=23
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.15.129.90