NAME shared.rb DESCRIPTION super simple super power sharing of instance and class level code INSTALL gem install shared URIS http://rubyforge.org/projects/codeforpeople http://codeforpeople.com/lib/ruby/ HISTORY 1.0.0 - add Share/Shared methods - move from @@vars to closure based impl 0.4.5 - add Shared.for as 'shared' alias to rails' style const missing can trigger lib load for a call. usage: Shared.for(:name){ ... } 0.4.3 - added version info - move methods from Object to Kernel and made them private (thx Stefan Rusterholz) 0.4.2 initial version SAMPLES <========< samples/a.rb >========> ~ > cat samples/a.rb # shared.rb is a very simple and very powerful method of sharing code between # classes. # require 'shared' shared(:code) do def classname() self.class.name end end class Foo include shared(:code) end class Bar include shared(:code) end p Foo.new.classname #=> "Foo" p Bar.new.classname #=> "Bar" ~ > ruby samples/a.rb "Foo" "Bar" <========< samples/b.rb >========> ~ > cat samples/b.rb # shared.rb allows natural declaration of both instance and class-level # methods - it's more than simple module inclusion # require 'shared' shared('methods') do def self.class_method() 40 end def instance_method() 2 end end class C include shared('methods') end p(C.class_method + C.new.instance_method) #=> 42 ~ > ruby samples/b.rb 42 <========< samples/c.rb >========> ~ > cat samples/c.rb # shared.rb works equally well with individual objects in addition to the # normal class level usage # require 'shared' shared(:meta_tools) do def singleton_class &block singleton_class = class << self self end block ? singleton_class.module_eval(&block) : singleton_class end end a = %w( a b c ) a.extend shared(:meta_tools) a.singleton_class do def to_range() first .. last end end p a.to_range #=> "a".."c" ~ > ruby samples/c.rb "a".."c" <========< samples/d.rb >========> ~ > cat samples/d.rb # an example use-case for shared.rb is sharing code bewteen classes that # require both class level and instance level behaviour to be shared # require 'shared' shared(:acts_as_named) do validates_precence_of :name def to_html() " #{ name } " end end class Model def Model.validates_precence_of(*a) end def name() 'zaphod' end include shared(:acts_as_named) end p Model.new.to_html #=> " zaphod " ~ > ruby samples/d.rb " zaphod " <========< samples/e.rb >========> ~ > cat samples/e.rb # it's important to note that the shared code is injected into the reciever # fresh on each call and, in that way, the effect is rather macro like # require 'shared' share(:instance_tracker) do const_set :Instances, [] def self.instances() const_get :Instances end def self.new *a, &b obj = super ensure instances << obj end end class Foo include shared(:instance_tracker) end class Bar include shared(:instance_tracker) end 2.times{ Foo.new } 40.times{ Bar.new } p(Foo.instances.size + Bar.instances.size) ~ > ruby samples/e.rb 42