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.
···
On 9/28/05, Elf M. Sternberg <elf@drizzle.com> wrote: