Attributes-3.3.0

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 N. and Florian
Gross.

HISTORY
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

 #<Config:0x220b0 @port=80, @host="codeforpeople.org">

enjoy.

-a