Skip to content

Commit

Permalink
Add option to omit creating an instance reader method on class_attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
bensie committed Jun 19, 2011
1 parent 8d9bc64 commit ad06ddd
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
23 changes: 17 additions & 6 deletions activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/kernel/singleton_class'
require 'active_support/core_ext/module/remove_method'
require 'active_support/core_ext/array/extract_options'

class Class
# Declare a class-level attribute whose value is inheritable by subclasses.
Expand Down Expand Up @@ -56,11 +57,18 @@ 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]
options = attrs.extract_options!
instance_reader = options.fetch(:instance_reader, true)
instance_writer = options.fetch(:instance_writer, true)

attrs.each do |name|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
Expand All @@ -75,12 +83,15 @@ def self.#{name}=(val)
val
end
def #{name}
defined?(@#{name}) ? @#{name} : singleton_class.#{name}
end
if instance_reader
remove_possible_method :#{name}
def #{name}
defined?(@#{name}) ? @#{name} : singleton_class.#{name}
end
def #{name}?
!!#{name}
def #{name}?
!!#{name}
end
end
RUBY

Expand Down
6 changes: 6 additions & 0 deletions activesupport/test/core_ext/class/attribute_test.rb
Expand Up @@ -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'
Expand Down

0 comments on commit ad06ddd

Please sign in to comment.