#-- # Credit for original goes to David Heinemeier Hansson. #++ class Class # Creates a class-variable attribute that can # be accessed both on an instance and class level. # # NOTE These used to be a Module methods. But turns out # these to work as expected when included. The class-level # method is not carried along. So the are now just class # methods. Accordingly, #mattr will eventually be deprecated # so use #cattr instead. def cattr( *syms ) accessors, readers = syms.flatten.partition { |a| a.to_s =~ /=$/ } writers = accessors.collect{ |e| e.to_s.chomp('=').to_sym } readers.concat( writers ) cattr_writer( *writers ) cattr_reader( *readers ) return readers + accessors end alias_method :mattr, :cattr # deprecate # Creates a class-variable attr_reader that can # be accessed both on an instance and class level. # # class MyClass # @@a = 10 # cattr_reader :a # end # # MyClass.a #=> 10 # MyClass.new.a #=> 10 # def cattr_reader( *syms ) syms.flatten.each do |sym| class_eval(<<-EOS, __FILE__, __LINE__) def self.#{sym} @@#{sym} end def #{sym} @@#{sym} end EOS end return syms end alias_method :mattr_reader, :cattr_reader # deprecate # Creates a class-variable attr_writer that can # be accessed both on an instance and class level. # # class MyClass # cattr_writer :a # def a # @@a # end # end # # MyClass.a = 10 # MyClass.a #=> 10 # MyClass.new.a = 29 # MyClass.a #=> 29 # def cattr_writer(*syms) syms.flatten.each do |sym| class_eval(<<-EOS, __FILE__, __LINE__) def self.#{sym}=(obj) @@#{sym} = obj end def #{sym}=(obj) @@#{sym}=(obj) end EOS end return syms end alias_method :mattr_writer, :cattr_writer # deprecate # Creates a class-variable attr_accessor that can # be accessed both on an instance and class level. # # class MyClass # cattr_accessor :a # end # # MyClass.a = 10 # MyClass.a #=> 10 # mc = MyClass.new # mc.a #=> 10 # def cattr_accessor(*syms) m = [] m.concat( cattr_reader(*syms) ) m.concat( cattr_writer(*syms) ) m end alias_method :mattr_accessor, :cattr_accessor # deprecate end # _____ _ # |_ _|__ ___| |_ # | |/ _ \/ __| __| # | | __/\__ \ |_ # |_|\___||___/\__| # =begin test require 'test/unit' class TCModule < Test::Unit::TestCase class MockObject def initialize @@a = 10 end def b ; @@b ; end end def test_cattr assert_nothing_raised { MockObject.class_eval { cattr :a } } t = MockObject.new assert_equal( 10, t.a ) end def test_cattr_reader assert_nothing_raised { MockObject.class_eval { cattr_reader :a } } t = MockObject.new assert_equal( 10, t.a ) end def test_cattr_writer assert_nothing_raised { MockObject.class_eval { cattr_writer :b } } t = MockObject.new t.b = 5 assert_equal( 5, t.b ) end def test_cattr_accessor assert_nothing_raised { MockObject.class_eval { cattr_accessor :c } } t = MockObject.new t.c = 50 assert_equal( 50, t.c ) end end =end