From: Brian Mitchell Date: 2005-09-29T04:35:52+09:00 Subject: Re: Python to Ruby: Two puzzlements... On 9/28/05, Elf M. Sternberg wrote: > I'm afraid that I'm coming from Python, a B&D language where I'm used to > everything be spelled out cleanly, and although I programmed in Perl for > many years that was also many years ago. Ruby is baffling the heck out > of me. > > I've been looking at two examples, and I was wondering if someone could > explain to me what the Hell is going on. The first is from > http://redhanded.hobix.com/bits/hyperextended.html, and my question is > about the 'extend' keyword there. To start off, it is not a keyword. Rather it is a method that is found on an instance of Module (Class is a subclass of Module -- see Class.ancestors). > Where does that came from? I explained where it is defined but the extend keyword is also a bit trickier. It could be thought of as running include on the singleton class of an object. Particular gotchas are the order in which instance methods are looked up and called. class A def foo p 'A' end end module M def foo p 'M' end end class B include M def foo p 'B' end end a = A.new b = B.new puts 'class' a.foo b.foo puts 'extend' a.extend M a.foo b.extend M b.foo class << a def foo p 'a' end end # another way to do the above. def b.foo p 'b' end puts 'singleton class' a.foo b.foo > In what > object is it defined? Module is where extend is. The methods are in the singleton class. You can check this out by running at the end of the above script. C = Class.new c = C.new c.extend M class << c p self.ancestors end > It's just hanging there in space. In the same > breath, what does the 'super' keyword do in the append_features() > method, and why does it need a 'self' in front of it? ri Module#append_features will talk about how the default implementation adds constants, methods, and module variables. To maintain this it calls the overridden method explicitly using super. super is an example of a magic keyword. It will pass the arguments given to the current by default. > I've tried > reading ruby-docs without finding much illumination. > That is ok. This is what this mailing list is for. It is good to hear that some people try before they post still though... > module Mix > def inst_meth > puts 'inst_meth' > end > > module ClassMethods > def class_meth > puts 'class_meth' > end > end > > extend ClassMethods > > def self.append_features(klass) > super > klass.extend(ClassMethods) > end > end > This code, from what it looks like. Takes a module and appends the instance methods along with class methods (which usually don't follow). I haven't run it but it seems the ClassMethods module makes this more obvious. This is a useful technique which quite a few ruby projects have made use of (I think rails uses this). Read the comments on the RedHanded post has there are many other interesting improvements that can be made. > > Second, I've seen the following constructions: > > validates :url :with => %r{^http:.+\.(gif|jpg|png)$}i > %r{} or %r[] or %r|| etc... are just another nice way of defining regular expressions. > and > > check_associations %w(friends downloads links) > %w just creates an array from a space delliminated list. The escaping rules follow that of '. The other version is %W which escapes like " does. > I'm guessing that the "%r" and "%w" are the ruby equivalents of perl's > qr{} and qw{} constructs (does this mean there's a %qq() and %qx() as > well?), but I can't find documentation to that effect inside the > references available on-line. (And before someone says "Buy the > Pickaxe!" I'll just say that I spent my book budget this month on the > Rails book and any other purchases will have to wait until my next > paycheck.) Well, in due time... I will, however, tell you that it is worth the money for most people. Brian.