eco-friendly
metaprogramming
All metadata and reflection is accessed via the doodle method.
class Named < Doodle has :name end class Person < Named has :age, :kind => Integer do must "be >= 0" do |v| v >= 0 end end end pp Person.doodle.attributes # >> {:name=> # >> #<Doodle::DoodleAttribute:0x551d9c # >> @doodle_owner=#<Class:0x5a193c>, # >> @name=:name>, # >> :age=> # >> #<Doodle::DoodleAttribute:0x9a1f0 # >> @doodle_owner=#<Class:0x550438>, # >> @kind=[Integer], # >> @name=:age>}
If you want to see just those attributes defined in a specific class (i.e. exclude inherited attributes), pass false to the attributes method:
pp Person.doodle.attributes(false) # >> {:age=> # >> #<Doodle::DoodleAttribute:0x9a0ec # >> @doodle_owner=#<Class:0x5503d4>, # >> @kind=[Integer], # >> @name=:age>}
person = Person :name => "Corum", :age => 999 Person.doodle.keys # => [:name, :age] person.doodle.keys # => [:name, :age]
person.doodle.values # => ["Corum", 999]
person.doodle.key_values # => [[:name, "Corum"], [:age, 999]]
Validations belong to either the class as a whole or individual attributes. As attributes are themselves doodles, you need to access their metadata via their own doodle method:
class Person < Doodle has :name, :kind => String has :age, :kind => Integer do must "be >= 0" do |v| v >= 0 end end must "not be called Arthur" do name !~ /^Arthur$/ end end pp Person.doodle.validations puts pp Person.doodle.attributes[:age].doodle.validations # >> [#<Doodle::Validation:0x8b434 # >> @block=#<Proc:0x0058d07c@-:11>, # >> @message="not be called Arthur">] # >> # >> [#<Doodle::Validation:0x98224 # >> @block= # >> #<Proc:0x0057c330@/Users/ohalps01/work/doodle/lib/doodle/validation.rb:32>, # >> @message="be a kind of Integer">, # >> #<Doodle::Validation:0x8b4fc # >> @block=#<Proc:0x0058d234@-:7>, # >> @message="be >= 0">]
Like validations, conversions belong to the class or individual attributes:
class Person < Doodle has :name, :kind => String has :age, :kind => Integer do from String do |s| s.to_i end end end pp Person.doodle.attributes[:age].doodle.conversions # >> {String=>#<Proc:0x0058d270@-:7>}