G
Greg Weeks
When the following code is evaluated
def foo ; "foo" ; end
where does the method go? Here is what I would guess.
If the evaluation context of the def is a class, then the method is an
instance method of the class. If the evaluation context of the def is
not a class, then the method is a singleton method of the context
object.
This rule is ugly, but it almost always works. What I don't understand
is the one exception below. Here are the non-exceptions:
class X
def foo ; "foo" ; end # #method of X
end
X.new.foo # works
obj = []
class <<obj
def foo ; "foo" ; end # singleton method of obj
end
obj.foo # works
class Y
def def_foo
def foo ; "foo" ; end # singleton method of Y instances
end
end
y = Y.new
y.def_foo
y.foo # works
class Z
def Z.def_foo
def foo ; "foo" ; end # #method of Z
end
def_foo
end
Z.new.foo # works
And here is the exception:
module Definer
def def_foo
def foo ; "foo" ; end # class method of User !
end
end
class User
extend Definer
def_foo
end
User.foo # works!
User.new.foo # error!
Bug or feature? In particular, why should Z and User give different
results?
PS: All my talk of "execution context" I picked up off the street. I
don't find it discussed in "Programming Ruby" or "The Ruby Way".
def foo ; "foo" ; end
where does the method go? Here is what I would guess.
If the evaluation context of the def is a class, then the method is an
instance method of the class. If the evaluation context of the def is
not a class, then the method is a singleton method of the context
object.
This rule is ugly, but it almost always works. What I don't understand
is the one exception below. Here are the non-exceptions:
class X
def foo ; "foo" ; end # #method of X
end
X.new.foo # works
obj = []
class <<obj
def foo ; "foo" ; end # singleton method of obj
end
obj.foo # works
class Y
def def_foo
def foo ; "foo" ; end # singleton method of Y instances
end
end
y = Y.new
y.def_foo
y.foo # works
class Z
def Z.def_foo
def foo ; "foo" ; end # #method of Z
end
def_foo
end
Z.new.foo # works
And here is the exception:
module Definer
def def_foo
def foo ; "foo" ; end # class method of User !
end
end
class User
extend Definer
def_foo
end
User.foo # works!
User.new.foo # error!
Bug or feature? In particular, why should Z and User give different
results?
PS: All my talk of "execution context" I picked up off the street. I
don't find it discussed in "Programming Ruby" or "The Ruby Way".