aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib')
-rw-r--r--activesupport/lib/active_support/callbacks.rb18
-rw-r--r--activesupport/lib/active_support/concern.rb35
-rw-r--r--activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb22
-rw-r--r--activesupport/lib/active_support/dependencies.rb22
-rw-r--r--activesupport/lib/active_support/ordered_hash.rb11
-rw-r--r--activesupport/lib/active_support/ordered_options.rb16
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)