Add option to omit creating an instance reader method on class_attribute

This commit is contained in:
James Miller 2011-06-18 15:49:11 -07:00
parent 2fbb7504e2
commit 0ce5fb8a27
2 changed files with 26 additions and 7 deletions

@ -56,11 +56,22 @@ class Class
# object.setting # => false
# Base.setting # => true
#
# To opt out of the instance reader method, pass :instance_reader => false.
#
# object.setting # => NoMethodError
# object.setting? # => NoMethodError
#
# To opt out of the instance writer method, pass :instance_writer => false.
#
# object.setting = false # => NoMethodError
def class_attribute(*attrs)
instance_writer = !attrs.last.is_a?(Hash) || attrs.pop[:instance_writer]
instance_reader = true
instance_writer = true
if attrs.last.is_a?(Hash)
instance_accessors = attrs.pop
instance_reader = instance_accessors[:instance_reader]
instance_writer = instance_accessors[:instance_writer]
end
attrs.each do |name|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
@ -84,13 +95,15 @@ def #{name}
val
end
remove_possible_method :#{name}
def #{name}
defined?(@#{name}) ? @#{name} : self.class.#{name}
end
if instance_reader
remove_possible_method :#{name}
def #{name}
defined?(@#{name}) ? @#{name} : self.class.#{name}
end
def #{name}?
!!#{name}
def #{name}?
!!#{name}
end
end
RUBY

@ -60,6 +60,12 @@ def setup
assert_raise(NoMethodError) { object.setting = 'boom' }
end
test 'disabling instance reader' do
object = Class.new { class_attribute :setting, :instance_reader => false }.new
assert_raise(NoMethodError) { object.setting }
assert_raise(NoMethodError) { object.setting? }
end
test 'works well with singleton classes' do
object = @klass.new
object.singleton_class.setting = 'foo'