No description or website provided.
Ruby
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
samples
README
README.tmpl
a.rb
attributes1-5.0.2.gem
attributes1-5.0.3.gem
b.rb
gemspec.rb
gen_readme.rb
install.rb

README

NAME
  attributes.rb

INSTALL
  gem install attributes

URIS
  http://codeforpeople.com/lib/ruby
  http://rubyforge.org/projects/codeforpeople/
  http://codeforpeople.rubyforge.org/svn/

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.

  the implementation 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 along
  with concepts from the original traits lib

  key features provided by attributes are

    - ability to specify default values for attrs and definition time.  values
      can be literal objects or blocks, which are evaluated in the context of
      self to initialize the variable

    - classes remember which attributes they've defined and this information is
     available to client code

    - a whole suite of methods is defined by calls to #attributes including
     getter, setter, query (var?) and banger (var! - which forces
     re-initialization from the default value)

    - ability to define multiple attributes at once using key => value pairs

    - fast lookup of whether or not a class has defined a certain attribute

    - attributes can be defined on objects on a per singleton basis as well

    - getters acts as setters if an argument is given to them

    - block caching, calling an attribute with a block sets the instance
      variable to that block

  all this in < 100 lines of code

HISTORY
  5.0.1
    - removed wrong dep on pervasives from gemspec.rb

  5.0.0
    - added support for block caching. for example

        - simple block caching:

            class Filter 
              attribute :process
            end

            filter = Filter.new

            filter.process{|line| line.upcase}

            lines.each do |line|
              p filter.process.call(line)
            end

        - using block caching to delay block evaluation/class-factory:

            module MigrationDSL
              attribute :migration

              def migration_class
                model = self

                Class.new(::ActiveRecord::Migration) do
                  singleton_class =
                    class << self
                      self
                    end
                  singleton_class.module_eval{ attribute :model => model }
                  singleton_class.module_eval &model.migration
                end
              end
            end

            class Table < ActiveRecord::Base
              extend MigrationDSL
            end

            class Jobs < Table
              migration do
                def up
                  create_table model.table_name, :primary_key => model.primary_key do |t|
                    t.column 'vinyl_shoes', :text
                  end
                end

                def down
                  create_table model.table_name
                end
              end
            end

            ...

            JobsMigration = Jobs.migration_class

  4.1.0
    - 4.0.0 introduced a bug where a query (foo?) would not initialize a var -
      4.1.0 fixes that

  4.0.0
    - removed dependancy on, and bundle of, pervasives
    - faster.  as fast as normal method definition.
    - faster lookup for MyClass.attributes.include?('foobar')

  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 a suite of methods
    #
      require 'attributes'
    
      class C
        attribute 'a'
      end
    
      c = C.new
    
      c.a = 42
      p c.a                 #=> 42
      p 'forty-two' if c.a? #=> 'forty-two'
    
    #
    # attributes works on object too 
    #
      o = Object.new
      o.attribute 'answer' => 42
      p o.answer           #=> 42

  ~ > 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.  the
    # 'banger' method can be used to re-initialize a variable at any point whether
    # or not it's already been initialized.
    #
      require 'attributes'
    
      class C
        attribute :a => 42
        attribute(:b){ Float a }
      end
    
      c = C.new
      p c.a #=> 42
      p c.b #=> 42.0
    
      c.a = 43
      p c.a #=> 43
      c.a!
      p c.a #=> 42

  ~ > ruby samples/b.rb

    42
    42.0
    43
    42


  <========< 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 #=> 42

  ~ > 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:0x1fb58 @port=80, @host="codeforpeople.org">


  <========< samples/f.rb >========>

  ~ > cat samples/f.rb

    #
    # of course attributes works as well at class/module level as at instance
    # level
    #
      require 'attributes'
    
      module Logging 
        Level_names = {
          0 => 'INFO',
          # ...
          42 => 'DEBUG',
        }
    
        class << self
          attribute 'level' => 42
          attribute('level_name'){ Level_names[level] }
        end
      end
    
    p Logging.level
    p Logging.level_name

  ~ > ruby samples/f.rb

    42
    "DEBUG"