Skip to content
Browse files

Add option to Class#class_attribute for skipping the query method

  • Loading branch information...
1 parent ec8f59c commit 941986c7db3f4abaed6f859a4d7b93e6445039c4 @agis- agis- committed
View
6 activesupport/CHANGELOG.md
@@ -1,5 +1,11 @@
## Rails 4.0.0 (unreleased) ##
+* `Class#class_attribute` accepts an `instance_predicate` option which
+ defaults to `true`. If set to `false` the predicate method will not
+ be defined.
+
+ *Agis Anastasopoulos*
+
* `fast_xs` support has been removed. Use 'String#encode(xml: :attr)`.
* `ActiveSupport::Notifications::Instrumenter#instrument` should yield
View
8 activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -44,7 +44,8 @@ class Class
# Base.setting # => []
# Subclass.setting # => [:foo]
#
- # For convenience, a query method is defined as well:
+ # For convenience, an instance predicate method is defined as well.
+ # To skip it, pass <tt>instance_predicate: false</tt>.
#
# Subclass.setting? # => false
#
@@ -72,10 +73,11 @@ def class_attribute(*attrs)
# double assignment is used to avoid "assigned but unused variable" warning
instance_reader = instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
+ instance_predicate = options.fetch(:instance_predicate, true)
attrs.each do |name|
define_singleton_method(name) { nil }
- define_singleton_method("#{name}?") { !!public_send(name) }
+ define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
ivar = "@#{name}"
@@ -109,7 +111,7 @@ def class_attribute(*attrs)
self.class.public_send name
end
end
- define_method("#{name}?") { !!public_send(name) }
+ define_method("#{name}?") { !!public_send(name) } if instance_predicate
end
attr_writer name if instance_writer
View
9 activesupport/test/core_ext/class/attribute_test.rb
@@ -27,7 +27,7 @@ def setup
assert_equal 1, Class.new(@sub).setting
end
- test 'query method' do
+ test 'predicate method' do
assert_equal false, @klass.setting?
@klass.setting = 1
assert_equal true, @klass.setting?
@@ -48,7 +48,7 @@ def setup
assert_equal 1, object.setting
end
- test 'instance query' do
+ test 'instance predicate' do
object = @klass.new
assert_equal false, object.setting?
object.setting = 1
@@ -73,6 +73,11 @@ def setup
assert_raise(NoMethodError) { object.setting = 'boom' }
end
+ test 'disabling instance predicate' do
+ object = Class.new { class_attribute :setting, instance_predicate: false }.new
+ assert_raise(NoMethodError) { object.setting? }
+ end
+
test 'works well with singleton classes' do
object = @klass.new
object.singleton_class.setting = 'foo'
View
2 guides/source/active_support_core_extensions.md
@@ -1039,6 +1039,8 @@ For convenience `class_attribute` also defines an instance predicate which is th
When `:instance_reader` is `false`, the instance predicate returns a `NoMethodError` just like the reader method.
+If you do not want the instance predicate, pass `instance_predicate: false` and it will not be defined.
+
NOTE: Defined in `active_support/core_ext/class/attribute.rb`
#### `cattr_reader`, `cattr_writer`, and `cattr_accessor`

0 comments on commit 941986c

Please sign in to comment.
Something went wrong with that request. Please try again.