Submitted by: Gavin Kistner
This revision by: Gavin Kistner
Date: Thu Aug 09 15:56:55 -0400 2007
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 )
For both DRY and DSL purposes, it is desirable to be able to write the above instead as:
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
Unfortunately, defining a method currently returns no useful value:
class C memoized def fib( n ) ( n<2 ) ? 1 : fib(n-1) + fib(n-2) end end
irb(main):001:0> p( def foo; end ) nil
defto return the instance Method that was just created:
#Current behavior: p( def foo; end ) #=> nil #Proposed p( def foo; end ) #=> #<Method: Object#foo>
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
defto instead return a symbol that was the name of the method. A Symbol would be convenient for some existing methods, such as
However, as noted in the comments for that RCR, a single symbol is ambiguous without knowing the class which that method is defined in:
class C private def foo; end end
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.
classto return the class that was just created/opened, such as:
However, making this change would remove existing functionality of returning the value of the last statement inside the class block:
#Not existing or proposed; example only p( class C; end ) #=> C
# 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
Finally, note the various references to Python decorators in the old RCR, including on the subject.
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
Return to top
Copyright © 2006, Ruby Power and Light, LLC