Method Invocations

A method invocation expression has four parts:

  • An arbitrary expression whose value is the object on which the method is invoked. This expression is followed by . or :: to separate it from the method name that follows. The expression and separator are optional; if omitted, the method is invoked on self.

  • The name of the method being invoked. This is the only required piece of a method invocation expression.

  • The argument values being passed to the method. The list of arguments may be enclosed in parentheses, but these are usually optional. (Optional and required parentheses are discussed in detail in Methods and Parentheses.) If there is more than one argument, they are separated from each other with commas. The number and type of arguments required depend on the method definition. Some methods expect no arguments.

  • An optional block of code delimited by curly braces or by a do/end pair. The method may invoke this code using the yield keyword. This ability to associate arbitrary code with any method invocation is the basis for Ruby’s powerful iterator methods. We’ll learn much more about blocks associated with method invocations in Iterators and Enumerable Objects and Blocks.

A method name is usually separated from the object on which it is invoked with a .. :: is also allowed, but it is rarely used because it can make method invocations look more like constant reference expressions.

When the Ruby interpreter has the name of a method and an object on which it is to be invoked, it finds the appropriate definition of that named method using a process known as “method lookup” or “method name resolution.” The details are not important here, but they are explained thoroughly in Method Lookup.

The value of a method invocation expression is the value of the last evaluated expression in the body of the method. We’ll have more to say about method definitions, method invocations, and method return values in Chapter 6. Here, however, are some examples of method invocations:

puts "hello world"  # "puts" invoked on self, with one string arg
Math.sqrt(2)        # "sqrt" invoked on object Math with one arg
message.length      # "length" invoked on object message; no args
a.each {|x| p x }   # "each" invoked on object a, with an associated block

One of the method invocation examples shown earlier was message.length. You may be tempted to think of it as a variable reference expression, evaluating to the value of the variable length in the object message. This is not the case, however. Ruby has a very pure object-oriented programming model: Ruby objects may encapsulate any number of internal instance variables, but they expose only methods to the outside world. Because the length method expects no arguments and is invoked without optional parentheses, it looks like a variable reference. In fact, this is intentional. Methods like these are called attribute accessor methods, and we say that the message object has a length attribute.[4] As we’ll see, it is possible for the message object to define a method named length=. If this method expects a single argument, then it is an attribute setter method and Ruby invokes it in response to assignment. If such a method is defined, then these two lines of code would both invoke the same method:

message.length=(3)    # Traditional method invocation
message.length = 3    # Method invocation masquerading as assignment

Now consider the following line of code, assuming that the variable a holds an array:

a[0]

You might again think that this is a special kind of variable reference expression, where the variable in question is actually an array element. Again, however, this is method invocation. The Ruby interpreter converts the array access into this:

a.[](0)

The array access becomes an invocation of the method named [] on the array, with the array index as its argument. This array access syntax is not limited to arrays. Any object is allowed to define a method named []. When the object is “indexed” with square brackets, any values within the brackets will be passed to the method. If the [] method is written to expect three arguments, then you should put three comma-separated expressions within the square brackets.

Assignment to arrays is also done via method invocation. If the object o defines a method named []=, then the expression o[x]=y becomes o.[]=(x,y), and the expression o[x,y]=z becomes o.[]=(x,y,z).

We’ll see later in this chapter that many of Ruby’s operators are defined as methods, and expressions like x+y are evaluated as x.+(y), where the method name is +. The fact that many of Ruby’s operators are defined as methods means that you can redefine these operators in your own classes.

Now let’s consider this very simple expression:

x

If a variable named x exists (that is, if the Ruby interpreter has seen an assignment to x), then this is a variable reference expression. If no such variable exists, then this is an invocation of the method x, with no arguments, on self.

The Ruby-reserved word super is a special kind of method invocation expression. This keyword is used when creating a subclass of another class. By itself, super passes the arguments of the current method to the method with the same name in the superclass. It can also be used as if it were actually the name of a method and can be followed by an arbitrary argument list. The super keyword is covered in detail in Augmenting Behavior by Chaining.



[4] This is not to say that every no-argument method is an attribute accessor. The sort method of an array, for example, has no arguments, but it cannot be said to return an attribute value.

Get The Ruby Programming Language now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.