Previous Next Table of contents

2. Variables, constants and arguments

2.1 Does assignment to a variable or a constant generate a new copy of an object?

Variables and constants point some object. If they are not initialized, they point nil object. Variables and constants point other object by assignment.

So assignment never creates a new copy of an object, and let variables and constants on the left hand side point to the object expressed by the right hand side.

You can be satisfied with this explanation, but someone may want to know another story. This explanation has no defect, but in fact instances of Fixnum, NilClass, TrueClass, and FalseClass are contained directly in variables or constants. So these are copied by assignment. Other than these classes, every object is stored in some place in the memory, and variables or constants point those memory address. See the difference between immediate value and reference.

2.2 What is the definition of the scope of a local variable?

A new scope for a local variable is introduced in the toplevel, a class (module) definition, a method defintion. In a procedure block a new scope is introduced but you can access to a local variable outside the block.

The scope in a block is special because a local variable should be localized in Thread and Proc objects.

while, until, and for are control structures and the scope is shared with the outside of these structures. loop is a method and the appended block introduces a new scope.

2.3 When does a local variable become accessible?

The Ruby interpreter first reads in a script and analyzes it into a parsed tree. If parsing goes well according to the syntax, the parsed tree is interpreted to get the desired result.

A local variable becomes accessible after the first assignment statement of that variable appears in the first path.
for i in 1..2
  if i == 2
    print a
  else
    a = 1
  end
end
Putting this script into a file named test.rb, we get
test.rb:3: undefined local variable or method `a' for
   #<Object:0x40101f4c> (NameError)
      from test.rb:1:in `each'
      from test.rb:1
When i is 1, there occurs no error, and when i becomes 2, an error occurs. In the first phase of syntax analysis, the interpreter does not know that print a appears after a is assigned 1, and in the statement print a the interpreter does not know the local variable a. When executed, it searches for a method named a but fails and an error is reported.

On the other hand, next script does not raise an error.
a = 1 if false; print a
# ->nil
You are recommended to put an assignment statement like a = nil before accessing a local variable not to be bothered by such behaviour of local variables. There is an additional goodie of speeding up the access time to local variables if defined outside a block.

2.4 What is the definition of the scope of a constant?

A constant defined in a class/module definition can be accessed within the definition.

If another class/module definition is nested, then in the inner definition you can access the outer constants.

You can also access the constants in the superclass and included modules directly.

If you cannot access to a constant directly, you can access it using :: operator, designating the class/module name on the left hand side.

2.5 How is the actual argument passed to the formal argument?

The actual argument is assigned to the formal argument when the method is invoked. The meaning of assignment in Ruby is answered in assignment to a variable. If the object referred by the actual argument has a destructive method which alters the attribute of the object, please be careful for the unexpected effect.

2.6 Does assignment to the formal argument influence the actual argument?

A formal argument is a local variable. After assignment to a formal argument, the formal argument points another object, and the object pointed by the actual argument is not infulenced at all.

2.7 What happens if I send a message to the object pointed by the formal argument

The object pointed by a formal argument is the same as the object pointed by an actual argument. If the message changes the attribute of the object, the calling side is influenced by a method call. See destructive method.

2.8 What is the * prepended to an argument?

This is not a pointer, you C wizards! This is for passing arbitrary number of arguments to methods using an array.
def foo(*all)
  for e in all
    print e, " "
  end
end

foo(1, 2, 3)
# -> 1 2 3
In a method call context * denotes to expand an array to pass the elements as arguments.
a = [1, 2, 3]
foo(*a)
You can prepend * to the last argument of
  1. Left hand side of a multiple assignment.
  2. Right hand side of a multiple assignment.
  3. Definition of method formal arguments.
  4. Actual arguments in a method call.
  5. In when clause of case structure.
An example of (1) is
x, *y = [7, 8, 9]
and the result is x = 7, y = [8, 9].

In the following example, x is 7.
x, = [7, 8, 9]
Next returns x = [7, 8, 9].
x = [7, 8, 9]

2.9 What is the & prepended to an argument?

It is an argument to pass a Proc object. It is the last argument in the argument list.

2.10 Can I define a default value for a formal argument?

Yes, you can.

This default value is evaluated when the method is invoked. Any expression can be a default value and is evaluated using the scope of the method.

2.11 How to pass arguments to a block.

Actual arguments are assigned respectively to the formal arguments which lie in the top part of a block surrounded by ||. These arguments are local variables and, when an argument is already used outside the block, the scope is shared.

2.12 An unexpected change happens to the content of variables or constants.

Are you surprised at such an event?
A = a = b = "abc"; b << "d"; print a, " ", A
# ->abcd abcd
Assignment to a variable or a constant is used to refer later the object assigned to that variable or constant. The assigned is not the object itself but its reference. A variable can contain another reference later but the reference contained by a constant will never be changed.

If you apply a method to a variable or a constant, the method is applied to the object they are referring. The above example shows that << method changes the attribute of the object and "an unexpected event" happened. Numerics as objects do not have such a method to change their attribute, so such a problem never happens. A new object is returned if you apply a method to numerics.

We used a string in this example, but similar events happen to the objects which have a method to change their attributes.

2.13 Does the value of a constant ever change?

When a constant refers an object and is assigned a new object, a warning occurs.

The attribute of the object referred can be altered by a destructive method.
Previous Next Table of contents