From: Brian Candler Date: 2003-08-16T16:04:04+09:00 Subject: Re: Overloading () On Sat, Aug 16, 2003 at 07:54:08AM +0900, Dave Benjamin wrote: > I think I'm really asking the wrong question here. What I'd really like to > know about is "callable objects". The () is a syntactical construct that has > a different meaning in Ruby than in Python. In Ruby, () is optional. But > this isn't what I'm really asking. I'm asking how one might make an object > in Ruby behave like a method. > > irb(main):001:0> f = lambda {|x| x + 1} > => # > irb(main):002:0> f 5 > NameError: undefined method `f' for # > from (irb):2 > irb(main):003:0> f.call 5 > => 6 Well, you can *convert* your lambda into a method: f = lambda {|x| x + 1} class << self; self; end.instance_eval { define_method(:f,f) } f(5) # prints 6 (from http://www.rubygarden.org/ruby?SingletonTutorial ) > I understand that everything lives inside an object, so there are no free > functions, but there are certainly methods that behave like free functions; > I can create one of those things using "def". What I can't seem to do is > pass that method around and still call it without referencing the object > it's attached to. Or can I? You can create a 'Method' object and pass it around: def hello(x) puts "Hello #{x}" end m = method(:hello) # this is self.method(:hello) m.call("world!") m["everyone"] m is a first-class object and can be passed around. However, (1) m is still implicitly bound to an object ('self' in this case), even though you don't explicitly reference it in the call; and (2) you have to use one of the indirect call syntaxes to invoke it. I think it's more commonly used with an explicit object: class X def hello(x) puts "Hello #{x}" end end obj = X.new meth = obj.method(:hello) meth.call("world!") These days I almost never write a program with a 'def' at the top-level. I just wrap the whole lot in a class, and then stick MyClass.new.run (or whatever) at the end of the program. It just makes things much tidier and easier to reuse components. Regards, Brian.