Change def to return a Method instance (#15)

Submitted by: Gavin Kistner

This revision by: Gavin Kistner

Date: Thu Aug 09 15:56:55 -0400 2007

ABSTRACT

Currently, defining a method using the standard def foo; end syntax returns nil. Change def to instead return the Method that was just defined.

(This is a slightly revised version of )

PROBLEM

As noted in it is desirable to be able to define module methods that operate on a single method. Currently, this requires code like the following:
class C
  def fib( n )
    ( n<2 ) ? 1 : fib(n-1) + fib(n-2)
    end
  end

  # Assumes that memoized is designed to take a Method instance
  memoized( method( :fib ) )
end
For both DRY and DSL purposes, it is desirable to be able to write the above instead as:
class C
  memoized def fib( n )
    ( n<2 ) ? 1 : fib(n-1) + fib(n-2)
  end
end
Unfortunately, defining a method currently returns no useful value:
irb(main):001:0> p( def foo; end )
nil

PROPOSAL

Change def to return the instance Method that was just created:

#Current behavior:
p( def foo; end )
#=> nil    

#Proposed
p( def foo; end )
#=> #<Method: Object#foo>

ANALYSIS

This should cause no incompatibilities, as it seems very unlikely that any code relies on the current behavior of returning nil. It’s adding information not previously available (easily).

called for def to instead return a symbol that was the name of the method. A Symbol would be convenient for some existing methods, such as private:
class C
  private def foo; end
end
However, as noted in the comments for that RCR, a single symbol is ambiguous without knowing the class which that method is defined in:
irb(main):001:0> class C
irb(main):002:1>   def self.foo; end
irb(main):003:1>   private :foo
irb(main):004:1> end
NameError: undefined method `foo' for class `C'
        from (irb):3:in `private'
        from (irb):3

For this RCR to be truly beneficial and a good fit within the language, it would require three other changes:

1) Existing language methods that take symbols as arguments to refer to a method would also accept Method instances.

2) A new method Method#name should be added, allowing users to get a symbol referring to the name of the method.

3) A new method Method#owning_class should be added, allowing users to get a reference to the Class that the method was defined in.

It would seem consistent to also modify class to return the class that was just created/opened, such as:
#Not existing or proposed; example only
p( class C; end )
#=> C
However, making this change would remove existing functionality of returning the value of the last statement inside the class block:
# Existing behavior
irb(main):001:0> class C; def self.foo; end; end
=> nil
irb(main):002:0> class C; method :foo; end
=> #<Method: C.foo>

For this reason, this RCR does not advocate changing the value returned by class.

Finally, note the various references to Python decorators in the old RCR, including on the subject.

IMPLEMENTATION

I’m not proficient in C to supply an implementation. However, note the implementation in that showed how simple it was to modify eval.c to return a Symbol from def.

Comments

from David Black, Thu Aug 09 16:33:18 -0400 2007

Hi --

On Thu, 9 Aug 2007, rcrchive+15@rcrchive.net wrote:

> Welcome to the comment list for:
>
>  Change def to return a Method instance (RCR #15)

For some reasons RCRchive decided to create five copies of this RCR
(one copy *exactly* every minute for five minutes).  I have no idea
why....  If anyone has any possible explanations, please let me know.

I've deleted the last four, so it's now just this one.


David



Return to top

Copyright © 2006, Ruby Power and Light, LLC