|
|
|
|
|
by ubernostrum
6503 days ago
|
|
Well, except the example you've given isn't really "metaprogramming" in the sense I'm trying to get at. Here's a Python translation which shows why: def Monkey(word):
class _Monkey(object):
def shout(self):
print word
return _Monkey
class Chimp(Monkey("foo")):
pass
class Gorilla(Monkey("bar")):
pass
c = Chimp()
c.shout() # prints "foo"
g = Gorilla()
g.shout() # prints "bar"
In other words, the Ruby code you've provided is basically a class factory taking advantage of closures. The Python example shows that a bit more clearly.What I'm looking for is something equivalent to Python's "metaclass" declaration, which lets you completely control the way the class object is created. I've been told by fairly knowledgeable Rubyists that there isn't really an equivalent, and that after-the-fact monkeypatching or factory solutions like yours are the only way to come at the problem in Ruby. |
|
However it will let you subclass 'Module', which is the superclass of Class, and you can use this to achieve similar ends if not quite as elegantly.
The way class methods work wrt to inheritance is a bit different in ruby though, and gives you quite a lot of power to provide special behaviours to subclasses via class methods which can be called in the subclass class definition. The kind of "we provide a DSL for you to use in your class definitions to configure the subclass" tricks which (IIRC) tend to require metaclasses in python, don't require them in ruby.
There is also an 'inherited' class method callback on Class, which you can use to run code whenever a new class inherits from your class. And this can be used to achieve a lot of things that pythonistas might use metaclasses for.
On the whole I think anything possible in one language is possible in the other when it comes to metaprogramming, it's just a matter of how you go about it and how elegant it feels.