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 )
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
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>
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 fordef
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.
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.
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
.
Copyright © 2006, Ruby Power and Light, LLC
Comments
from David Black, Thu Aug 09 16:33:18 -0400 2007