URLS http://rubyforge.org/projects/codeforpeople/ http://codeforpeople.com/lib/ruby/traits INSTALL yes|sudo gem install traits ABOUT traits.rb is set of attr_* like methods on steroids, caffeine, and botox. it encourages better living through meta-programming and uniform access priciples. traits.rb supports smart inheritence of class attributes and a fistful of hooks for veryifying and munging attr values. VERSION 0.10.0 HISTORY 0.10.0 - removed use of additional instance var to denote whether a value had been set. now the test is only 'defined? @#{ name }'. 0.9.2 - fixed a bug where list traits, for example trait 'letters' => %w[ a b c ] were flattened in a way that exploded trait initialization - streamlined TraitInit module - added OpenTraits class and otraits method conf = otraits{ port 42 host 'forty-two' } p conf.port #=> 42 p conf.host #=> 'forty-two' conf.username 'zaphod' p conf #=> {"username"=>"zaphod", "port"=>42, "host"=>"forty-two"} 0.9.0 - luke kaines made quite a few suggestions and bug reports that enabled this release including making a few methods indifferent about string/symbol args/keys and the introduction of a simple method 'trait_init' that can be used to create keyword based initializers, eg: require 'traits' class C include TraitInit trait :a, :type => Integer trait :b, :type => Integer def initialize opts = {} trait_init opts end end C::new :a => 4, :b => 2 0.8.0 - traits now supports a whole slew of hooks that can be registered to fire pre or post setting an attribute, to cast a value to another type, to munge a value destructively, to require only certain types, to require a certain ducktype signature, and to validate arguments passed. check out sample/m.rb, sample/n.rb, or sample.o.rb to see it in action. the mechanism is quite flexible allowing method names, lambdas of varying arity, and lists of either/or to be passed to any hook. - you can find a gem for trais on codeforpeople - but i've still not coded up automated updating from codeforpeople to rubyforge so it won't show up as a remote gem yet. 0.7.0 - patched in the support i had written eariler for 'hooks' to be called pre/post setting a trait. plus shortcut to 'validate' traits which simply sets up a 'pre' hook which is used as a predicate. eg: class C; trait 'number', 'validate' => proc{|n| Numeric === n} pre and post hooks are used in the same way, eg: class C trait 'a', 'pre' => proc{|val| p "#{ val } to set with"}, 'post' => proc{|val| p "#{ val } set"}, end but the really cool thing is that all of these blocks are both passed the value in question but also evaluate with 'self' set appropriately. eg class Car positive_int = lambda{|n| Fixnum === n and n > 0} legal = proc{|s| s < speed_limit} trait 'speed_limit', 'validate' => positive_int, 'default' => 42 trait 'speed', 'validate' => legal end c = Car::new c.speed = 115 works as you'd expect: (eval):14:in `speed=': validation of speed=(115) failed! (ArgumentError) from a.rb:13 0.6.0 - fixed bug in where a default trait given as an empty array, eg: class C; has 'a' => []; end was exploded into the empty list when passed to the setter to initialize the default value. 0.5.0 - general code cleanup 0.4.0 - tweaked writer code so multiple values can be passed to setters - tweaked method of running blocks to use instance_eval so explicit 'this' arg is no longer needed (though it can still be used) 0.3.0 added ability of default values to be specified with block for deferred context sensitive initialization (see sample/c.rb) 0.1.0 completely reworked impl so NO parsing of inspect strings is required - it's all straight methods (albeit quite confusing ones) now. the interface is unchanged. 0.0.0 initial version AUTHOR ara [dot] t [dot] howard [at] noaa [dot] gov SAMPLES @samples CAVEATS this library is experimental and subject to change - though it has not for several versions and much of my code hinges is on it now so you can expect the interface to be stable in the near future - the only changes planned are those that fix bugs or add features. LICENSE same as ruby's