diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2006-01-29 00:37:39 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2006-01-29 00:37:39 +0000 |
commit | 01b1a8772928fbf31180341356981b95d0581413 (patch) | |
tree | 16d9939a713b79c91f5a14c799fb4e12790ecfff /activesupport/lib/active_support/core_ext | |
parent | 94046542e274f76ec9d31721a73a19e4b651fbfc (diff) | |
download | rails-01b1a8772928fbf31180341356981b95d0581413.tar.gz rails-01b1a8772928fbf31180341356981b95d0581413.tar.bz2 rails-01b1a8772928fbf31180341356981b95d0581413.zip |
Added reusable reloading support through the inclusion of the Relodable module that all subclasses of ActiveRecord::Base, ActiveRecord::Observer, ActiveController::Base, and ActionMailer::Base automatically gets [DHH]. Added auto-loading support for classes in modules, so Conductor::Migration will look for conductor/migration.rb and Conductor::Database::Settings will look for conductor/database/settings.rb [Nicholas Seckar]. Refactored extensions to module, class, and object in active support [DHH]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3493 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activesupport/lib/active_support/core_ext')
-rw-r--r-- | activesupport/lib/active_support/core_ext/blank.rb | 16 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/class.rb | 3 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/class/attribute_accessors.rb | 44 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb | 115 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/class/removal.rb | 21 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/exception.rb | 1 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/module.rb | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/module/attribute_accessors.rb | 44 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/module/inclusion.rb | 15 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/object.rb | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/object/extending.rb (renamed from activesupport/lib/active_support/core_ext/object_and_class.rb) | 47 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/object/misc.rb | 16 |
12 files changed, 280 insertions, 46 deletions
diff --git a/activesupport/lib/active_support/core_ext/blank.rb b/activesupport/lib/active_support/core_ext/blank.rb index 791cdc5705..f7fbea3e89 100644 --- a/activesupport/lib/active_support/core_ext/blank.rb +++ b/activesupport/lib/active_support/core_ext/blank.rb @@ -1,4 +1,16 @@ -# The methods here are provided to speed up function blank? in class Object +class Object #:nodoc: + # "", " ", nil, [], and {} are blank + def blank? + if respond_to?(:empty?) && respond_to?(:strip) + empty? or strip.empty? + elsif respond_to?(:empty?) + empty? + else + !self + end + end +end + class NilClass #:nodoc: def blank? true @@ -35,4 +47,4 @@ class Numeric #:nodoc: def blank? false end -end +end
\ No newline at end of file diff --git a/activesupport/lib/active_support/core_ext/class.rb b/activesupport/lib/active_support/core_ext/class.rb new file mode 100644 index 0000000000..7bacdb3903 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/class.rb @@ -0,0 +1,3 @@ +require File.dirname(__FILE__) + '/class/attribute_accessors' +require File.dirname(__FILE__) + '/class/inheritable_attributes' +require File.dirname(__FILE__) + '/class/removal'
\ No newline at end of file diff --git a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb new file mode 100644 index 0000000000..93a7d48f69 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb @@ -0,0 +1,44 @@ +# Extends the class object with class and instance accessors for class attributes, +# just like the native attr* accessors for instance attributes. +class Class # :nodoc: + def cattr_reader(*syms) + syms.flatten.each do |sym| + class_eval(<<-EOS, __FILE__, __LINE__) + unless defined? @@#{sym} + @@#{sym} = nil + end + + def self.#{sym} + @@#{sym} + end + + def #{sym} + @@#{sym} + end + EOS + end + end + + def cattr_writer(*syms) + syms.flatten.each do |sym| + class_eval(<<-EOS, __FILE__, __LINE__) + unless defined? @@#{sym} + @@#{sym} = nil + end + + def self.#{sym}=(obj) + @@#{sym} = obj + end + + def #{sym}=(obj) + @@#{sym} = obj + end + EOS + end + end + + def cattr_accessor(*syms) + cattr_reader(*syms) + cattr_writer(*syms) + end +end diff --git a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb new file mode 100644 index 0000000000..2e70a64436 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb @@ -0,0 +1,115 @@ +# Retain for backward compatibility. Methods are now included in Class. +module ClassInheritableAttributes # :nodoc: +end + +# Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of +# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements +# to, for example, an array without those additions being shared with either their parent, siblings, or +# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy. +class Class # :nodoc: + def class_inheritable_reader(*syms) + syms.each do |sym| + class_eval <<-EOS + def self.#{sym} + read_inheritable_attribute(:#{sym}) + end + + def #{sym} + self.class.#{sym} + end + EOS + end + end + + def class_inheritable_writer(*syms) + syms.each do |sym| + class_eval <<-EOS + def self.#{sym}=(obj) + write_inheritable_attribute(:#{sym}, obj) + end + + def #{sym}=(obj) + self.class.#{sym} = obj + end + EOS + end + end + + def class_inheritable_array_writer(*syms) + syms.each do |sym| + class_eval <<-EOS + def self.#{sym}=(obj) + write_inheritable_array(:#{sym}, obj) + end + + def #{sym}=(obj) + self.class.#{sym} = obj + end + EOS + end + end + + def class_inheritable_hash_writer(*syms) + syms.each do |sym| + class_eval <<-EOS + def self.#{sym}=(obj) + write_inheritable_hash(:#{sym}, obj) + end + + def #{sym}=(obj) + self.class.#{sym} = obj + end + EOS + end + end + + def class_inheritable_accessor(*syms) + class_inheritable_reader(*syms) + class_inheritable_writer(*syms) + end + + def class_inheritable_array(*syms) + class_inheritable_reader(*syms) + class_inheritable_array_writer(*syms) + end + + def class_inheritable_hash(*syms) + class_inheritable_reader(*syms) + class_inheritable_hash_writer(*syms) + end + + def inheritable_attributes + @inheritable_attributes ||= {} + end + + def write_inheritable_attribute(key, value) + inheritable_attributes[key] = value + end + + def write_inheritable_array(key, elements) + write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil? + write_inheritable_attribute(key, read_inheritable_attribute(key) + elements) + end + + def write_inheritable_hash(key, hash) + write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil? + write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash)) + end + + def read_inheritable_attribute(key) + inheritable_attributes[key] + end + + def reset_inheritable_attributes + inheritable_attributes.clear + end + + private + def inherited_with_inheritable_attributes(child) + inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes) + child.instance_variable_set('@inheritable_attributes', inheritable_attributes.dup) + end + + alias inherited_without_inheritable_attributes inherited + alias inherited inherited_with_inheritable_attributes +end diff --git a/activesupport/lib/active_support/core_ext/class/removal.rb b/activesupport/lib/active_support/core_ext/class/removal.rb new file mode 100644 index 0000000000..8fc4d728b3 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/class/removal.rb @@ -0,0 +1,21 @@ +class Class #:nodoc: + def remove_subclasses + Object.remove_subclasses_of(self) + end + + def subclasses + Object.subclasses_of(self).map { |o| o.to_s } + end + + def remove_class(klass) + if klass.to_s.include? "::" + modules = klass.to_s.split("::") + final_klass = modules.pop + + final_module = modules.inject(Object) { |final_type, part| final_type.const_get(part) } + final_module.send(:remove_const, final_klass) rescue nil + else + Object.send(:remove_const, klass.to_s) rescue nil + end + end +end
\ No newline at end of file diff --git a/activesupport/lib/active_support/core_ext/exception.rb b/activesupport/lib/active_support/core_ext/exception.rb index 2541f37495..0b65af7bf8 100644 --- a/activesupport/lib/active_support/core_ext/exception.rb +++ b/activesupport/lib/active_support/core_ext/exception.rb @@ -1,5 +1,4 @@ class Exception - alias :clean_message :message TraceSubstitutions = [] diff --git a/activesupport/lib/active_support/core_ext/module.rb b/activesupport/lib/active_support/core_ext/module.rb new file mode 100644 index 0000000000..0f46631e65 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/module.rb @@ -0,0 +1,2 @@ +require File.dirname(__FILE__) + '/module/inclusion' +require File.dirname(__FILE__) + '/module/attribute_accessors'
\ No newline at end of file diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb new file mode 100644 index 0000000000..fe4f8a4fc0 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb @@ -0,0 +1,44 @@ +# Extends the module object with module and instance accessors for class attributes, +# just like the native attr* accessors for instance attributes. +class Module # :nodoc: + def mattr_reader(*syms) + syms.each do |sym| + class_eval(<<-EOS, __FILE__, __LINE__) + unless defined? @@#{sym} + @@#{sym} = nil + end + + def self.#{sym} + @@#{sym} + end + + def #{sym} + @@#{sym} + end + EOS + end + end + + def mattr_writer(*syms) + syms.each do |sym| + class_eval(<<-EOS, __FILE__, __LINE__) + unless defined? @@#{sym} + @@#{sym} = nil + end + + def self.#{sym}=(obj) + @@#{sym} = obj + end + + def #{sym}=(obj) + @@#{sym} = obj + end + EOS + end + end + + def mattr_accessor(*syms) + mattr_reader(*syms) + mattr_writer(*syms) + end +end diff --git a/activesupport/lib/active_support/core_ext/module/inclusion.rb b/activesupport/lib/active_support/core_ext/module/inclusion.rb new file mode 100644 index 0000000000..124c4551bc --- /dev/null +++ b/activesupport/lib/active_support/core_ext/module/inclusion.rb @@ -0,0 +1,15 @@ +class Module + def remove_classes_including + included_in_classes.each { |klass| Class.remove_class(klass) } + end + + def included_in_classes + classes = [] + ObjectSpace.each_object(Class) { |k| classes << k if k.included_modules.include?(self) } + + classes.reverse.inject([]) do |unique_classes, klass| + unique_classes << klass unless unique_classes.collect { |k| k.to_s }.include?(klass.to_s) + unique_classes + end + end +end
\ No newline at end of file diff --git a/activesupport/lib/active_support/core_ext/object.rb b/activesupport/lib/active_support/core_ext/object.rb new file mode 100644 index 0000000000..3dd6deaba1 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/object.rb @@ -0,0 +1,2 @@ +require File.dirname(__FILE__) + '/object/extending' +require File.dirname(__FILE__) + '/object/misc'
\ No newline at end of file diff --git a/activesupport/lib/active_support/core_ext/object_and_class.rb b/activesupport/lib/active_support/core_ext/object/extending.rb index d44afbd839..8c638f83c2 100644 --- a/activesupport/lib/active_support/core_ext/object_and_class.rb +++ b/activesupport/lib/active_support/core_ext/object/extending.rb @@ -4,7 +4,7 @@ class Object #:nodoc: Object.send(:remove_const, subclass.to_s) rescue nil end end - + def subclasses_of(*superclasses) subclasses = [] ObjectSpace.each_object(Class) do |k| @@ -20,41 +20,16 @@ class Object #:nodoc: end def copy_instance_variables_from(object, exclude = []) - exclude += object.protected_instance_variables if - object.respond_to? :protected_instance_variables + exclude += object.protected_instance_variables if object.respond_to? :protected_instance_variables instance_variables = object.instance_variables - exclude.map { |name| name.to_s } - instance_variables.each do |name| - instance_variable_set name, object.instance_variable_get(name) - end + instance_variables.each { |name| instance_variable_set(name, object.instance_variable_get(name)) } end def extend_with_included_modules_from(object) object.extended_by.each { |mod| extend mod } end - - # "", " ", nil, [], and {} are blank - def blank? - if respond_to?(:empty?) && respond_to?(:strip) - empty? or strip.empty? - elsif respond_to?(:empty?) - empty? - else - !self - end - end - def suppress(*exception_classes) - begin yield - rescue Exception => e - raise unless exception_classes.any? {|cls| e.kind_of? cls} - end - end - - def with_options(options) - yield ActiveSupport::OptionMerger.new(self, options) - end - def instance_values instance_variables.inject({}) do |values, name| values[name[1..-1]] = instance_variable_get(name) @@ -62,23 +37,9 @@ class Object #:nodoc: end end - def to_json - ActiveSupport::JSON.encode(self) - end - unless defined? instance_exec # 1.9 def instance_exec(*arguments, &block) block.bind(self)[*arguments] end end -end - -class Class #:nodoc: - def remove_subclasses - Object.remove_subclasses_of(self) - end - - def subclasses - Object.subclasses_of(self).map { |o| o.to_s } - end -end +end
\ No newline at end of file diff --git a/activesupport/lib/active_support/core_ext/object/misc.rb b/activesupport/lib/active_support/core_ext/object/misc.rb new file mode 100644 index 0000000000..f599eee6f0 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/object/misc.rb @@ -0,0 +1,16 @@ +class Object #:nodoc: + def with_options(options) + yield ActiveSupport::OptionMerger.new(self, options) + end + + def to_json + ActiveSupport::JSON.encode(self) + end + + def suppress(*exception_classes) + begin yield + rescue Exception => e + raise unless exception_classes.any? { |cls| e.kind_of?(cls) } + end + end +end
\ No newline at end of file |