diff options
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support/callbacks.rb | 18 | ||||
-rw-r--r-- | activesupport/lib/active_support/concern.rb | 35 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb | 22 | ||||
-rw-r--r-- | activesupport/lib/active_support/dependencies.rb | 22 | ||||
-rw-r--r-- | activesupport/lib/active_support/ordered_hash.rb | 11 | ||||
-rw-r--r-- | activesupport/lib/active_support/ordered_options.rb | 16 |
6 files changed, 112 insertions, 12 deletions
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 1c7802f7de..24e407c253 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -419,7 +419,10 @@ module ActiveSupport @_keyed_callbacks ||= {} @_keyed_callbacks[name] ||= begin str = send("_#{kind}_callbacks").compile(name, object) - class_eval "def #{name}() #{str} end", __FILE__, __LINE__ + class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def #{name}() #{str} end + protected :#{name} + RUBY_EVAL true end end @@ -483,7 +486,11 @@ module ActiveSupport end end - # Skip a previously defined callback for a given type. + # Skip a previously defined callback. + # + # class Writer < Person + # skip_callback :validate, :before, :check_membership, :if => lambda { self.age > 18 } + # end # def skip_callback(name, *filter_list, &block) __update_callbacks(name, filter_list, block) do |chain, type, filters, options| @@ -523,7 +530,8 @@ module ActiveSupport # This macro accepts the following options: # # * <tt>:terminator</tt> - Indicates when a before filter is considered - # to be halted. + # to halted. This is a string to be eval'ed and has the result of the + # very filter available in the <tt>result</tt> variable: # # define_callbacks :validate, :terminator => "result == false" # @@ -568,7 +576,9 @@ module ActiveSupport # # would trigger <tt>Audit#before_save</tt> instead. That's constructed by calling # <tt>"#{kind}_#{name}"</tt> on the given instance. In this case "kind" is "before" and - # "name" is "save". + # "name" is "save". In this context ":kind" and ":name" have special meanings: ":kind" + # refers to the kind of callback (before/after/around) and ":name" refers to the + # method on which callbacks are being defined. # # A declaration like # diff --git a/activesupport/lib/active_support/concern.rb b/activesupport/lib/active_support/concern.rb index eb31f7cad4..2d87e8d0e5 100644 --- a/activesupport/lib/active_support/concern.rb +++ b/activesupport/lib/active_support/concern.rb @@ -1,3 +1,38 @@ +# A typical module looks like this +# +# module M +# def self.included(base) +# base.send(:extend, ClassMethods) +# base.send(:include, InstanceMethods) +# scope :foo, :conditions => { :created_at => nil } +# end +# +# module ClassMethods +# def cm; puts 'I am a class method'; end +# end +# +# module InstanceMethods +# def im; puts 'I am an instance method'; end +# end +# end +# +# By using <tt>ActiveSupport::Concern</tt> the above module could instead be written as: +# +# module M +# extend ActiveSupport::Concern +# +# included do +# scope :foo, :conditions => { :created_at => nil } +# end +# +# module ClassMethods +# def cm; puts 'I am a class method'; end +# end +# +# module InstanceMethods +# def im; puts 'I am an instance method'; end +# end +# end module ActiveSupport module Concern def self.extended(base) diff --git a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb index 92d6dbadd4..e844cf50d1 100644 --- a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb +++ b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb @@ -5,6 +5,10 @@ require 'active_support/core_ext/array/extract_options' module ClassInheritableAttributes # :nodoc: end +# It is recommend to use <tt>class_attribute</tt> over methods defined in this file. Please +# refer to documentation for <tt>class_attribute</tt> for more information. Officially it is not +# deprected but <tt>class_attribute</tt> is faster. +# # Allows attributes to be shared within an inheritance hierarchy. 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 @@ -12,6 +16,24 @@ end # # The copies of inheritable parent attributes are added to subclasses when they are created, via the # +inherited+ hook. +# +# class Person +# class_inheritable_accessor :hair_colors +# end +# +# Person.hair_colors = [:brown, :black, :blonde, :red] +# Person.hair_colors #=> [:brown, :black, :blonde, :red] +# Person.new.hair_colors #=> [:brown, :black, :blonde, :red] +# +# To opt out of the instance writer method, pass :instance_writer => false. +# To opt out of the instance reader method, pass :instance_reader => false. +# +# class Person +# class_inheritable_accessor :hair_colors :instance_writer => false, :instance_reader => false +# end +# +# Person.new.hair_colors = [:brown] # => NoMethodError +# Person.new.hair_colors # => NoMethodError class Class # :nodoc: def class_inheritable_reader(*syms) options = syms.extract_options! diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index 2b80bd214f..1b93eac7ee 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -276,14 +276,22 @@ module ActiveSupport #:nodoc: end def depend_on(file_name, swallow_load_errors = false, message = "No such file to load -- %s.rb") - path = search_for_file(file_name) - require_or_load(path || file_name) - rescue LoadError => load_error - unless swallow_load_errors - if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1] - raise LoadError.new(message % file_name).copy_blame!(load_error) + #path = search_for_file(file_name) + require_or_load(file_name) + rescue LoadError + begin + if path = search_for_file(file_name) + require_or_load(path) + else + raise + end + rescue LoadError => load_error + unless swallow_load_errors + if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1] + raise LoadError.new(message % file_name).copy_blame!(load_error) + end + raise end - raise end end diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb index 6b563b9063..2e8d538d0b 100644 --- a/activesupport/lib/active_support/ordered_hash.rb +++ b/activesupport/lib/active_support/ordered_hash.rb @@ -4,8 +4,17 @@ YAML.add_builtin_type("omap") do |type, val| ActiveSupport::OrderedHash[val.map(&:to_a).map(&:first)] end -# OrderedHash is namespaced to prevent conflicts with other implementations module ActiveSupport + # The order of iteration over hashes in Ruby 1.8 is undefined. For example, you do not know the + # order in which +keys+ will return keys, or +each+ yield pairs. <tt>ActiveSupport::OrderedHash</tt> + # implements a hash that preserves insertion order, as in Ruby 1.9: + # + # oh = ActiveSupport::OrderedHash.new + # oh[:a] = 1 + # oh[:b] = 2 + # oh.keys # => [:a, :b], this order is guaranteed + # + # <tt>ActiveSupport::OrderedHash</tt> is namespaced to prevent conflicts with other implementations. class OrderedHash < ::Hash #:nodoc: def to_yaml_type "!tag:yaml.org,2002:omap" diff --git a/activesupport/lib/active_support/ordered_options.rb b/activesupport/lib/active_support/ordered_options.rb index 61ccb79211..7fc2b45b51 100644 --- a/activesupport/lib/active_support/ordered_options.rb +++ b/activesupport/lib/active_support/ordered_options.rb @@ -1,5 +1,21 @@ require 'active_support/ordered_hash' +# Usually key value pairs are handled something like this: +# +# h = ActiveSupport::OrderedOptions.new +# h[:boy] = 'John' +# h[:girl] = 'Mary' +# h[:boy] # => 'John' +# h[:girl] # => 'Mary' +# +# Using <tt>OrderedOptions</tt> above code could be reduced to: +# +# h = ActiveSupport::OrderedOptions.new +# h.boy = 'John' +# h.girl = 'Mary' +# h.boy # => 'John' +# h.girl # => 'Mary' +# module ActiveSupport #:nodoc: class OrderedOptions < OrderedHash def []=(key, value) |