aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/core_ext/class
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2010-01-31 18:13:56 -0800
committerJeremy Kemper <jeremy@bitsweat.net>2010-02-01 02:02:41 -0800
commit8ae25a8e41168801590fdb95891cc5990b4db21c (patch)
treede2e639915fa8717dd96d37c6b6997cbf7c6771e /activesupport/lib/active_support/core_ext/class
parent209235165266ff39f2d14d02b497d7d703788104 (diff)
downloadrails-8ae25a8e41168801590fdb95891cc5990b4db21c.tar.gz
rails-8ae25a8e41168801590fdb95891cc5990b4db21c.tar.bz2
rails-8ae25a8e41168801590fdb95891cc5990b4db21c.zip
Introduce class_attribute to declare inheritable class attributes. Writing an attribute on a subclass behaves just like overriding the superclass reader method. Unifies and replaces most usage of cattr_accessor, class_inheritable_attribute, superclass_delegating_attribute, and extlib_inheritable_attribute.
Diffstat (limited to 'activesupport/lib/active_support/core_ext/class')
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute.rb36
1 files changed, 36 insertions, 0 deletions
diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb
new file mode 100644
index 0000000000..d74219cb93
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -0,0 +1,36 @@
+require 'active_support/core_ext/object/metaclass'
+require 'active_support/core_ext/module/delegation'
+
+class Class
+ # Declare a class-level attribute whose value is inheritable and
+ # overwritable by subclasses:
+ #
+ # class Base
+ # class_attribute :setting
+ # end
+ #
+ # class Subclass < Base
+ # end
+ #
+ # Base.setting = true
+ # Subclass.setting # => true
+ # Subclass.setting = false
+ # Subclass.setting # => false
+ # Base.setting # => true
+ #
+ # This matches normal Ruby method inheritance: think of writing an attribute
+ # on a subclass as overriding the reader method.
+ #
+ # For convenience, a query method is defined as well:
+ #
+ # Subclass.setting? # => false
+ def class_attribute(*attrs)
+ attrs.each do |attr|
+ metaclass.send(:define_method, attr) { }
+ metaclass.send(:define_method, "#{attr}?") { !!send(attr) }
+ metaclass.send(:define_method, "#{attr}=") do |value|
+ metaclass.send(:define_method, attr) { value }
+ end
+ end
+ end
+end