Joe Cutler
Joe Cutler

Reputation: 43

Why do method definitions return symbols?

When you define a method, it returns a symbol with the same name as the method. Is there a point to this? Or is it just there as validation that you created it?

Like so:

def something
   ...
end
# => :something

Upvotes: 4

Views: 1409

Answers (4)

Jörg W Mittag
Jörg W Mittag

Reputation: 369458

IRb always displays the result of calling inspect on the value of the last expression that was evaluated. It doesn't matter whether that expression is a literal expression, a conditional expression, a message send, a class definition expression or a method definition expression.

Everything returns a value in Ruby, i.e. everything is an expression, there is no such thing as a statement in Ruby.

In the past, the return value of a method definition expression was undefined. Most Ruby implementations simply returned nil from a method definition expression, but Rubinius for example returned the CompiledMethod object for the method that was defined.

With Ruby 2.1, the return value of a method definition expression was standardized to be the Symbol corresponding to the method's name. This allows you to use the method definition expression as an argument in methods that expect the name of a method as an argument.

Some examples:

# Before Ruby 2.0:
def foo; end
private :foo

# After Ruby 2.0:
private def foo; end # similar for `protected`, `public`, `module_function`

# Before Ruby 2.0:
def map; end
alias_method :collect, :map

# After Ruby 2.0:
alias_method :collect, def map; end

On a personal note, I would have preferred a method definition expression to evaluate to an UnboundMethod object corresponding to that method, and methods like public, private, protected, alias_method, module_function etc. should be amended to accept UnboundMethods in addition to Symbols and Strings.

Upvotes: 11

sawa
sawa

Reputation: 168101

The person who proposed this had in mind a usage like this:

private def foo
  ...
end
protected def bar
  ...
end

Methods such as public, private, protected take symbols as arguments. The point was to make use of this syntax.

Upvotes: 5

Jesper
Jesper

Reputation: 4555

All method defs return symbols in Ruby >=2.1 (not just the ones in IRB).

For example:

class Foo
  p def bar; end
end
# => prints :bar

Why is this interesting?

You may have noticed that there are many methods, particularly class-level methods, that take the symbolized name of another method as an argument. You may be familiar with before_filter in Rails controllers. Since method defs return symbols, you could potentially do this:

class MyController < ApplicationController
  before_filter def my_filter
     # do stuff
  end
end

Upvotes: 2

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

IRB respects the ruby standard “the result of last executed statement is returned from method.” Imagine the code:

def a
  def b
    # do stuff
  end
end

What is the result of execution this code? It follows:

a
# => :b
a.class
# => Symbol < Object

That said, IRB executes the method definition and returns/prints out it’s result. Which is, apparently, a Symbol instance.

Upvotes: 0

Related Questions