From: Ross Bamford Date: 2006-02-28T02:18:59+09:00 Subject: Re: Dynamic stuff and books On Tue, 2006-02-28 at 01:38 +0900, Mc Osten wrote: > I started using ruby a couple of weeks ago and it's time to make a couple > of questions :) > This is a long post, so I'm gonna write a short summary > I'll skip to the bits I might be able to help with :) > > 2. I wanted to know what happens if I do > > class A > def foo > end > end > > a = A.new > a.foo > > I found that it is *not* the same than > > a.send(:foo) > > I mean, if I redefine send, send is not called in "a.foo". > I thought I could redefine __send__, but ruby has not the same opinion on > the matter. :) > For example in Python I can do this redefinining __getattribute__ (I know > it's not good to go on a language ng talking about another language). In > fact this is even more radical... > > Is there a function that is called when I call a.foo? Or it's just a lookup > in a.methods? Can I trap this? The __send__ message how is handled? > I've been puzzled by this before, but I think a.foo calls are dispatched directly by Ruby, although send and __send__ will be used explicitly in other code, including the standard libraries. Even if this were not the case I guess you'd be unlikely to see _all_ calls go through __send__ (I'm thinking of methods implemented in C). You can do stuff like this, though, if you want to trap calls to a given method, whether it's implemented in Ruby or C: class A def foo "foo" end end # ... later ... class A alias :__old_foo :foo def foo # do something __old_foo end end Maybe what you need, or maybe not... > And are "attr" and "attr_writer" functions? What kind of functions are > them? Is there a place on the net where are explained in detail these > subjects? A book? [ ref 1. ] > attr and friends are singleton methods (a bit like class methods) on class Module, and are used in the scope of class or module definitions. They're an example of metaprogramming - when called, they create new instance methods on the class being defined, almost as if you'd 'def'ed them yourself (although they're faster since they, like attr(.*) itself, is implemented in C). You might find some enlightenment on the technique in a recent Ruby Quiz: http://www.rubyquiz.com/quiz67.html > 3. Module syntax > What is the difference between :: and .? I suppose they do the very same > thing. Am I correct? Ruby tries to be flexible, but where there's ambiguity this isn't always possible: module MadMod ACONST = 5 class << self def Amethod "A" end def Bmethod(a) a.to_s end def cmethod "C" end end end MadMod.ACONST NoMethodError: undefined method `ACONST' for MadMod2:Module from (irb):84 from :0 MadMod::ACONST # => 5 MadMod.Amethod # => "A" MadMod::Amethod NameError: uninitialized constant MadMod2::Amethod from (irb):82 from :0 MadMod.Bmethod(10) # => "10" MadMod::Bmethod(10) # => "10" MadMod.cmethod # => "C" MadMod::cmethod # => "C" Notice the last four (B and cmethod), where there is no ambiguity (Bmethod takes arguments, and so cannot be a constant, while cmethod lacks the initial lowercase letter that identifies constants). Ruby allows either :: or . to be used here, but generally you should probably stick to using :: for constant references, and . for method calls since it avoids any confusion for the parser and (more importantly) reader. Hope that helps, -- Ross Bamford - rosco@roscopeco.REMOVE.co.uk