NAME attributes.rb INSTALL gem install attributes URIS http://rubyforge.org/projects/codeforpeople/ http://codeforpeople.com/lib/ruby SYNOPSIS attributes.rb provides a set of attr_* like method with several user friendly additions. attributes.rb is similar to the traits.rb package but sacrifices a few features for simplicity of implementation: attributes.rb is only 42 lines of code. the implimentation of attributes.rb borrows many of the best ideas from the metakoans.rb ruby quiz http://www.rubyquiz.com/quiz67.html in particular the solutions of Christian Neukirchen and Florian Gross. HISTORY 3.7.0 small patch to use 'instance_variable_defined?' instead of defined? keyword 3.5.0 migrated to a pervasives based impl to attributes should work on any object - even blankslate objects 3.3.0 moved to an instance variable-less model using an module level closure for the attributes list SAMPLES <========< samples/a.rb >========> ~ > cat samples/a.rb # # basic usage is like attr, but note that attribute defines three methods, # getter, setter, and query # require 'attributes' class C attribute 'a' end c = C.new c.a = 42 # setter p c.a # getter p 'forty-two' if c.a? # query # # also not that attribute(s) works as well for objects as classes # o = Object.new o.attribute 'answer' => 42 p o.answer ~ > ruby samples/a.rb 42 "forty-two" 42 <========< samples/b.rb >========> ~ > cat samples/b.rb # # default values may be given either directly or as a block which will be # evaluated in the context of self. in both cases (value or block) the # default is set only once and only if needed - it's a lazy evaluation. # require 'attributes' class C attribute :a => 42 attribute(:b){ Float a } end c = C.new p c.a p c.b ~ > ruby samples/b.rb 42 42.0 <========< samples/c.rb >========> ~ > cat samples/c.rb # # multiple values may by given, plain names and key/val pairs may be mixed. # require 'attributes' class C attributes 'x', 'y' => 0b101000, 'z' => 0b10 end c = C.new c.x = c.y + c.z p c.x ~ > ruby samples/c.rb 42 <========< samples/d.rb >========> ~ > cat samples/d.rb # # a nice feature is that all attributes are enumerated in the class. this, # combined with the fact that the getter method is defined so as to delegate # to the setter when an argument is given, means bulk initialization and/or # attribute traversal is very easy. # require 'attributes' class C attributes %w( x y z ) def attributes self.class.attributes end def initialize attributes.each_with_index{|a,i| send a, i} end def to_hash attributes.inject({}){|h,a| h.update a => send(a)} end def inspect to_hash.inspect end end c = C.new p c.attributes p c c.x 'forty-two' p c.x ~ > ruby samples/d.rb ["x", "y", "z"] {"x"=>0, "y"=>1, "z"=>2} "forty-two" <========< samples/e.rb >========> ~ > cat samples/e.rb # # my favourite element of attributes is that getters can also be setters. # this allows incredibly clean looking code like # require 'attributes' class Config attributes %w( host port) def initialize(&block) instance_eval &block end end conf = Config.new{ host 'codeforpeople.org' port 80 } p conf ~ > ruby samples/e.rb #