From: David Alan Black Date: 2001-10-27T22:17:08+09:00 Subject: [ruby-talk:23621] Re: sleeping, calling methods inside class defs Hello -- On Sat, 27 Oct 2001, Tobias Reif wrote: > ruby 1.6.3 (2001-03-19) [i386-cygwin] > > Hi, > > 1. Why is the following sleeping? > > It just sleeps forever; how can I achieve it that it uses the method > above, not the sleep method?. > > ----- > class Tobi > > def sleep > print "rzzzzz..\n" > end > > sleep > > end > ----- Because the bare call to sleep is a call to Kernel#sleep. If you want to call the instance method defined in class Tobi, you need an instance of class Tobi :-) > 2. I know this is basic, but I don't get it: > ----- > class Tobi > > def hi > print "hi!\n" > end > > hi > > end > ----- > gives NameError: :7: undefined local variable or method `hi' for Tobi:Class Same idea. Executed in the context of the class definition, "hi" doesn't refer to anything. Compare this: irb 1> def hi; puts "hi"; end ==>nil irb 2> class Tobi; hi; end hi Here, the hi method is visible from inside the class definition, because it's in an outer scope. > ----- > class Tobi > > def hi > print "hi!\n" > end > > self.hi > > end > ----- > gives 7: undefined method `hi' for Tobi:Class (NameError) Same principle. The "self." doesn't change anything. > ----- > class Tobi > > def hi > print "hi!\n" > end > > end > > Tobi.new.hi > ----- > works; but how can I use the method inside the class? Make it a class method: class Tobi def Tobi.hi puts "hi" end hi end or: class Tobi class << self def hi puts "hi" end end hi end Note that there's a consistent underlying principle to all of this: Given object o and method m, if you call m in the context of o (when self is o), Ruby looks in o's class (and that class's ancestry, etc.) for an instance method called m. So if o is the Class object Tobi, then the search is for an instance method called hi in the class of o, which is the class Class. There is no instance method called "hi" in class Class. (There is one in class Tobi, but that isn't relevant unless "hi" is called by a Tobi object.) > ----- > class Tobi > > def hey > print "hey!\n" > end > > def hey_ho > hey > print "ho!\n" > end > > end > > Tobi.new.hey_ho > ----- > here I can call the first method inside the second, when calling the > second method from outside the class def. That's because hey_ho is executing in the context of the new Tobi object, which also has knowledge of its other instance methods (such as hey). > How to call a method inside the class def? > > ----- > class Tobi > > def hey > print "hey!\n" > end > > def hey_ho > hey > print "ho!\n" > end > > @hey_ho = self.hey_ho > > end > ----- > doesn't work. See above. Here, self is the Class object "Tobi". It has no instance method called hey_ho. That is: Tobi defines an instance method hey_ho for *its* instances -- but class Tobi is an instance of class Class, not of class Tobi. David -- David Alan Black home: dblack@candle.superlink.net work: blackdav@shu.edu Web: http://pirate.shu.edu/~blackdav