Afficher un message
Vieux 14/09/2007, 21h05   #1
Phlip
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut metaprogramming to generate list of class-specific attributes

Rubyists:

Here's a test case illustrates the problem. Then we'll have a candidate fix
and some questions.

class Kozmik
def self.acts_as_frog(species)
@@frog_list << species
end
@@frog_list = []
cattr_accessor :frog_list
end

class Toad < Kozmik
acts_as_frog :bufo
acts_as_frog :kermit
end

class BullFrog < Kozmik
acts_as_frog :tree
acts_as_frog :riparian
end

def test_fun_with_metaclasses
assert_equal [:tree, :riparian], BullFrog.frog_list
assert_equal [:bufo, :kermit], Toad.frog_list
end

Suppose we need an 'acts_as_' system to generate some methods for our target
classes. And suppose one method is a list of all the arguments passed to
each acts_as_() in each specific class.

The above test fails because @@ occupies the entire inheritance chain. So
both frog_list() class-methods return [:tree, :riparian, :bufo, :kermit].
The fix seems to be to reach into the meta-class for each derived class:

class Kozmik
def self.acts_as_frog(species)
@frog_list ||= []
@frog_list << species
self.class.send :attr_accessor, :frog_list
end
end

Is that as clean and lean as it could be? Is there some way to do this with
even fewer lines?

Next question: Couldn't class Kozmik be a module instead?

--
Phlip
http://www.oreilly.com/catalog/9780596510657/
^ assert_xpath
  Réponse avec citation
 
Page generated in 0,06307 seconds with 9 queries