From 9b8ee8e006db581eb34dc0fa1d230653b7a1c956 Mon Sep 17 00:00:00 2001 From: zackham Date: Tue, 2 Apr 2013 13:18:24 -0700 Subject: Escape multibyte line terminators in JSON encoding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, json/encoding respects the JSON spec (as it should) which disallows \n and \r inside strings, escaping them as expected. Unfortunately, ECMA-262 (Javascript) disallows not only \n and \r in strings, but "Line Terminators" which includes U+2028 and U+2029. See here: http://bclary.com/2004/11/07/#a-7.3 This pull request adds U+2028 and U+2029 to be escaped. # Why?  It's very common to see something like this in a Rails template: If U+2028 or U+2029 are part of any attributes output in the to_json call, you will end up with an exception. In Chrome: Uncaught SyntaxError: Unexpected token ILLEGAL  # Why not? This is JSON encoding, and the JSON spec is specific about how to  encode strings. U+2028 and U+2029 don't get special treatment. Just trying to start a discussion... what do you do in your apps to deal with this? Is there a convention I'm missing? --- activesupport/lib/active_support/json/encoding.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index 9bf1ea35b3..71dfbf3323 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -98,6 +98,8 @@ module ActiveSupport "\010" => '\b', "\f" => '\f', "\n" => '\n', + "\xe2\x80\xa8" => '\u2028', + "\xe2\x80\xa9" => '\u2029', "\r" => '\r', "\t" => '\t', '"' => '\"', @@ -121,9 +123,9 @@ module ActiveSupport def escape_html_entities_in_json=(value) self.escape_regex = \ if @escape_html_entities_in_json = value - /[\x00-\x1F"\\><&]/ + /\xe2\x80(\xa8|\xa9)|[\x00-\x1F"\\><&]/ else - /[\x00-\x1F"\\]/ + /\xe2\x80(\xa8|\xa9)|[\x00-\x1F"\\]/ end end -- cgit v1.2.3 From 14254d82a90b8aa4bd81f7eeebe33885bf83c378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hrvoje=20=C5=A0imi=C4=87?= Date: Wed, 17 Apr 2013 16:02:13 +0200 Subject: documentation fixes for Array.wrap and AR::Validations::AssociatedValidator --- activesupport/lib/active_support/core_ext/array/wrap.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/array/wrap.rb b/activesupport/lib/active_support/core_ext/array/wrap.rb index 1245768870..152eb02218 100644 --- a/activesupport/lib/active_support/core_ext/array/wrap.rb +++ b/activesupport/lib/active_support/core_ext/array/wrap.rb @@ -15,12 +15,12 @@ class Array # # * If the argument responds to +to_ary+ the method is invoked. Kernel#Array # moves on to try +to_a+ if the returned value is +nil+, but Array.wrap returns - # such a +nil+ right away. + # +nil+ right away. # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, Kernel#Array # raises an exception, while Array.wrap does not, it just returns the value. - # * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array. + # * It does not call +to_a+ on the argument, but returns an empty array if argument is +nil+. # - # The last point is particularly worth comparing for some enumerables: + # The second point is easily explained with some enumerables: # # Array(foo: :bar) # => [[:foo, :bar]] # Array.wrap(foo: :bar) # => [{:foo=>:bar}] @@ -29,10 +29,10 @@ class Array # # [*object] # - # which for +nil+ returns [], and calls to Array(object) otherwise. + # which returns [] for +nil+, but calls to Array(object) otherwise. # - # Thus, in this case the behavior may be different for +nil+, and the differences with - # Kernel#Array explained above apply to the rest of objects. + # The differences with Kernel#Array explained above + # apply to the rest of objects. def self.wrap(object) if object.nil? [] -- cgit v1.2.3 From df24b8790f22384a068fece7042f04ffd2fcb33e Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Fri, 19 Apr 2013 13:20:11 +0530 Subject: fix HashWithIndifferentAccess#to_hash behaviour --- .../lib/active_support/hash_with_indifferent_access.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb index 837db05dcc..b6c18fa54b 100644 --- a/activesupport/lib/active_support/hash_with_indifferent_access.rb +++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb @@ -229,7 +229,11 @@ module ActiveSupport # Convert to a regular hash with string keys. def to_hash - Hash.new(default).merge!(self) + _new_hash= {} + each do |key, value| + _new_hash[convert_key(key)] = convert_value(value,true) + end + Hash.new(default).merge!(_new_hash) end protected @@ -237,9 +241,9 @@ module ActiveSupport key.kind_of?(Symbol) ? key.to_s : key end - def convert_value(value) + def convert_value(value, _convert_for_to_hash = false) if value.is_a? Hash - value.nested_under_indifferent_access + _convert_for_to_hash ? value.to_hash : value.nested_under_indifferent_access elsif value.is_a?(Array) value = value.dup if value.frozen? value.map! { |e| convert_value(e) } -- cgit v1.2.3 From d7d2f2bb15646d5ed80e6aa225dfc0426b6a88ef Mon Sep 17 00:00:00 2001 From: Tomohiko Himura Date: Thu, 25 Apr 2013 21:43:06 +0900 Subject: remove unused require not used remove_possible_method --- activesupport/lib/active_support/core_ext/date/conversions.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/date/conversions.rb b/activesupport/lib/active_support/core_ext/date/conversions.rb index cdf606f28c..0637fe4929 100644 --- a/activesupport/lib/active_support/core_ext/date/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date/conversions.rb @@ -1,7 +1,6 @@ require 'date' require 'active_support/inflector/methods' require 'active_support/core_ext/date/zones' -require 'active_support/core_ext/module/remove_method' class Date DATE_FORMATS = { -- cgit v1.2.3 From e8e2f010afc29669e20b3f2461e1595b122220b8 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Tue, 30 Apr 2013 19:24:41 -0300 Subject: Fix typos in deprecation proxy docs [ci skip] --- activesupport/lib/active_support/deprecation/proxy_wrappers.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb index 485dc91063..a03a66b96b 100644 --- a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb +++ b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb @@ -25,7 +25,7 @@ module ActiveSupport end end - # This DeprecatedObjectProxy transforms object to depracated object. + # This DeprecatedObjectProxy transforms object to deprecated object. # # @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!") # @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!", deprecator_instance) @@ -52,7 +52,7 @@ module ActiveSupport end # This DeprecatedInstanceVariableProxy transforms instance variable to - # depracated instance variable. + # deprecated instance variable. # # class Example # def initialize(deprecator) @@ -93,7 +93,7 @@ module ActiveSupport end end - # This DeprecatedConstantProxy transforms constant to depracated constant. + # This DeprecatedConstantProxy transforms constant to deprecated constant. # # OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST') # OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST', deprecator_instance) -- cgit v1.2.3 From d7da403dde3a037a014741420bb7c6e7c7521a48 Mon Sep 17 00:00:00 2001 From: Brian Morearty Date: Wed, 1 May 2013 04:32:20 -0700 Subject: Revert "Object#in? also accepts multiple parameters" This reverts commit ebf69ab1636df74c76332c53bcd3d8494fb91b45. `in?` must not take multiple parameters because its behavior would be ambiguous: # Test if "B" is included in a list of names with `"B".in?(*names)`: names = ["BMorearty"] "B".in?(*names) # => true names = ["BMorearty","rubyduo"] "B".in?(*names) # => false Conflicts: activesupport/lib/active_support/core_ext/object/inclusion.rb activesupport/test/core_ext/object/inclusion_test.rb --- .../active_support/core_ext/object/inclusion.rb | 28 +++++++--------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/object/inclusion.rb b/activesupport/lib/active_support/core_ext/object/inclusion.rb index 3fec465ec0..b5671f66d0 100644 --- a/activesupport/lib/active_support/core_ext/object/inclusion.rb +++ b/activesupport/lib/active_support/core_ext/object/inclusion.rb @@ -1,25 +1,15 @@ class Object - # Returns true if this object is included in the argument(s). Argument must be - # any object which responds to +#include?+ or optionally, multiple arguments can be passed in. Usage: + # Returns true if this object is included in the argument. Argument must be + # any object which responds to +#include?+. Usage: # - # characters = ['Konata', 'Kagami', 'Tsukasa'] - # 'Konata'.in?(characters) # => true + # characters = ["Konata", "Kagami", "Tsukasa"] + # "Konata".in?(characters) # => true # - # character = 'Konata' - # character.in?('Konata', 'Kagami', 'Tsukasa') # => true - # - # This will throw an ArgumentError if a single argument is passed in and it doesn't respond + # This will throw an ArgumentError if the argument doesn't respond # to +#include?+. - def in?(*args) - if args.length > 1 - args.include? self - else - another_object = args.first - if another_object.respond_to? :include? - another_object.include? self - else - raise ArgumentError.new 'The single parameter passed to #in? must respond to #include?' - end - end + def in?(another_object) + another_object.include?(self) + rescue NoMethodError + raise ArgumentError.new("The parameter passed to #in? must respond to #include?") end end -- cgit v1.2.3 From 6fa575bb4f744315470cc971804dd6d09b5b987f Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Thu, 2 May 2013 09:41:19 +0530 Subject: Use faster Array.new instead of []*padding --- activesupport/lib/active_support/core_ext/array/grouping.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/array/grouping.rb b/activesupport/lib/active_support/core_ext/array/grouping.rb index 640e6e9328..dbddc7a7b4 100644 --- a/activesupport/lib/active_support/core_ext/array/grouping.rb +++ b/activesupport/lib/active_support/core_ext/array/grouping.rb @@ -25,7 +25,7 @@ class Array # subtracting from number gives how many to add; # modulo number ensures we don't add group of just fill. padding = (number - size % number) % number - collection = dup.concat([fill_with] * padding) + collection = dup.concat(Array.new(padding, fill_with)) end if block_given? -- cgit v1.2.3 From 796ed59e20dc739f1c3b195692a60d8e5d97c166 Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Thu, 2 May 2013 09:49:40 +0530 Subject: document String#to_time exception --- activesupport/lib/active_support/core_ext/string/conversions.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/string/conversions.rb b/activesupport/lib/active_support/core_ext/string/conversions.rb index d2a2db32bb..6691fc0995 100644 --- a/activesupport/lib/active_support/core_ext/string/conversions.rb +++ b/activesupport/lib/active_support/core_ext/string/conversions.rb @@ -15,6 +15,7 @@ class String # "2012-12-13 06:12".to_time # => 2012-12-13 06:12:00 +0100 # "2012-12-13T06:12".to_time # => 2012-12-13 06:12:00 +0100 # "2012-12-13T06:12".to_time(:utc) # => 2012-12-13 05:12:00 UTC + # "12/13/2012".to_time # => ArgumentError: argument out of range def to_time(form = :local) parts = Date._parse(self, false) return if parts.empty? -- cgit v1.2.3 From 6f6c0b0ae2bdbcff0da6b2be450a7d21816a27a6 Mon Sep 17 00:00:00 2001 From: Tomohiko Himura Date: Thu, 2 May 2013 16:02:00 +0900 Subject: Fixes Dependency bug in Active Support DateTime defined in date.rb --- activesupport/lib/active_support/core_ext/date_time/calculations.rb | 1 + activesupport/lib/active_support/core_ext/date_time/conversions.rb | 1 + activesupport/lib/active_support/core_ext/date_time/zones.rb | 1 + 3 files changed, 3 insertions(+) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/date_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_time/calculations.rb index 9f0864d9bb..f347f09293 100644 --- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb @@ -1,3 +1,4 @@ +require 'date' require 'active_support/deprecation' class DateTime diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb index b7d8414a9d..df07917d19 100644 --- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb @@ -1,3 +1,4 @@ +require 'date' require 'active_support/inflector/methods' require 'active_support/core_ext/time/conversions' require 'active_support/core_ext/date_time/calculations' diff --git a/activesupport/lib/active_support/core_ext/date_time/zones.rb b/activesupport/lib/active_support/core_ext/date_time/zones.rb index 6457ffbaf6..01a627f8af 100644 --- a/activesupport/lib/active_support/core_ext/date_time/zones.rb +++ b/activesupport/lib/active_support/core_ext/date_time/zones.rb @@ -1,3 +1,4 @@ +require 'date' require 'active_support/core_ext/time/zones' class DateTime -- cgit v1.2.3 From 58151ce461e559b7ba8a05a2fa9c9628f19c771b Mon Sep 17 00:00:00 2001 From: wangjohn Date: Thu, 2 May 2013 16:16:18 -0400 Subject: Improving the performance of callbacks by keeping a hash of the callbacks in the CallbackChain, so you don't have to iterate over all callbacks when checking for duplicates. Benchmark results when the tests in activerecord/test/cases/associations_test.rb were run with and without the change: == On master (when scanning all of the callbacks): --------------------------------------------------------- % cumulative self self total time seconds seconds calls ms/call ms/call name --------------------------------------------------------- 1.85 9.26 0.82 18412 0.04 0.05 ActiveSupport::Callbacks::Callback#matches? 1.22 12.32 0.54 18412 0.03 0.08 ActiveSupport::Callbacks::Callback#duplicates? 0.93 14.61 0.41 19600 0.02 0.21 ActiveSupport::Callbacks::CallbackChain#remove_duplicates Finished tests in 1.217065s, 30.4010 tests/s, 53.4072 assertions/s. --------------------------------------------------------- == On my branch (when using a hash to check callback duplication): --------------------------------------------------------- % cumulative self self total time seconds seconds calls ms/call ms/call name --------------------------------------------------------- 0.15 29.63 0.06 1188 0.05 0.72 ActiveSupport::Callbacks::CallbackChain#handle_duplicates 0.00 40.50 0.00 84 0.00 0.12 ActiveSupport::Callbacks::Callback#matches? 0.00 40.50 0.00 84 0.00 0.12 ActiveSupport::Callbacks::Callback#duplicates? 0.00 40.50 0.00 91 0.00 0.22 ActiveSupport::Callbacks::CallbackChain#scan_and_remove_duplicates Finished tests in 1.117757s, 33.1020 tests/s, 58.1522 assertions/s. --------------------------------------------------------- --- activesupport/lib/active_support/callbacks.rb | 44 ++++++++++++++++++++------- 1 file changed, 33 insertions(+), 11 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 893c2500d7..f0389d0a1c 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -132,6 +132,10 @@ module ActiveSupport @@_callback_sequence += 1 end + def object_filter? + @_is_object_filter + end + def matches?(_kind, _filter) if @_is_object_filter _filter_matches = @filter.to_s.start_with?(_method_name_for_object_filter(_kind, _filter, false)) @@ -337,6 +341,7 @@ module ActiveSupport :terminator => "false", :scope => [ :kind ] }.merge!(config) + @callbacks_hash = Hash.new { |h, k| h[k] = [] } end def compile @@ -361,20 +366,37 @@ module ActiveSupport private - def append_one(callback) - remove_duplicates(callback) - push(callback) - end + def append_one(callback) + handle_duplicates(callback) + push(callback) + end - def prepend_one(callback) - remove_duplicates(callback) - unshift(callback) - end + def prepend_one(callback) + handle_duplicates(callback) + unshift(callback) + end - def remove_duplicates(callback) - delete_if { |c| callback.duplicates?(c) } - end + # We check to see if this callback already exists. If it does (i.e. if + # +callback.duplicates?(c)+ for any callback +c+ in the list of + # callbacks), then we delete the previously defined callback. + # + # We make use of the rep-invariant that only one callback exists which + # might match the new callback. The +@callbacks_hash+ is keyed on the + # +kind+ and +filter+ of the callback, the attributes used to check if + # two callbacks match. + def handle_duplicates(callback) + if callback.object_filter? + scan_and_remove_duplicates(callback) + else + hash_key = [callback.kind, callback.filter] + delete @callbacks_hash[hash_key] if @callbacks_hash[hash_key] + @callbacks_hash[hash_key] = callback + end + end + def scan_and_remove_duplicates(callback) + delete_if { |c| callback.duplicates?(c) } + end end module ClassMethods -- cgit v1.2.3 From ffaceaa8cf1381acbf1becf0f50cade88eafdc4c Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Fri, 3 May 2013 11:59:52 +0100 Subject: Work around change in how MiniTest detects SIGINFO MiniTest 4.7.3 detects the presence of SIGINFO and stores the answer in a constant. It seems that MiniTest 4.7.4 changes this, and instead relies on an info_signal method being implemented on the runner object. In ActiveSupport::Testing::Isolation, we use ProxyTestResult to stand in for the runner object. This object implements `method_missing`, and as such its #info_signal method has a truthy return value. This results in MiniTest trying to install the SIGINFO handler on platforms where SIGINFO does not exists. To fix, I am simply defining an explicit ProxyTestResult#info_signal method. --- activesupport/lib/active_support/testing/isolation.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/testing/isolation.rb b/activesupport/lib/active_support/testing/isolation.rb index d70d971538..e16b73a036 100644 --- a/activesupport/lib/active_support/testing/isolation.rb +++ b/activesupport/lib/active_support/testing/isolation.rb @@ -40,6 +40,10 @@ module ActiveSupport def method_missing(name, *args) @calls << [name, args] end + + def info_signal + Signal.list['INFO'] + end end module Isolation -- cgit v1.2.3 From 30f297bef5fec202ee6b26e67c9e45fb7a500251 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Fri, 3 May 2013 12:44:49 +0100 Subject: Revert "Merge pull request #10433 from wangjohn/making_callbacks_more_performant" This reverts commit 09751fdc847c25237891a8fcb0c2312e39bbe86d, reversing changes made to 6a5ab08d21c4284a05f5e34484b18a91d4e5c50c. This change caused a failure in actionpack/test/abstract/callbacks_test.rb. --- activesupport/lib/active_support/callbacks.rb | 44 +++++++-------------------- 1 file changed, 11 insertions(+), 33 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index f0389d0a1c..893c2500d7 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -132,10 +132,6 @@ module ActiveSupport @@_callback_sequence += 1 end - def object_filter? - @_is_object_filter - end - def matches?(_kind, _filter) if @_is_object_filter _filter_matches = @filter.to_s.start_with?(_method_name_for_object_filter(_kind, _filter, false)) @@ -341,7 +337,6 @@ module ActiveSupport :terminator => "false", :scope => [ :kind ] }.merge!(config) - @callbacks_hash = Hash.new { |h, k| h[k] = [] } end def compile @@ -366,37 +361,20 @@ module ActiveSupport private - def append_one(callback) - handle_duplicates(callback) - push(callback) - end + def append_one(callback) + remove_duplicates(callback) + push(callback) + end - def prepend_one(callback) - handle_duplicates(callback) - unshift(callback) - end + def prepend_one(callback) + remove_duplicates(callback) + unshift(callback) + end - # We check to see if this callback already exists. If it does (i.e. if - # +callback.duplicates?(c)+ for any callback +c+ in the list of - # callbacks), then we delete the previously defined callback. - # - # We make use of the rep-invariant that only one callback exists which - # might match the new callback. The +@callbacks_hash+ is keyed on the - # +kind+ and +filter+ of the callback, the attributes used to check if - # two callbacks match. - def handle_duplicates(callback) - if callback.object_filter? - scan_and_remove_duplicates(callback) - else - hash_key = [callback.kind, callback.filter] - delete @callbacks_hash[hash_key] if @callbacks_hash[hash_key] - @callbacks_hash[hash_key] = callback - end - end + def remove_duplicates(callback) + delete_if { |c| callback.duplicates?(c) } + end - def scan_and_remove_duplicates(callback) - delete_if { |c| callback.duplicates?(c) } - end end module ClassMethods -- cgit v1.2.3 From 0e8a3bc8ae8f462b54e088778b604b3fbdb32c53 Mon Sep 17 00:00:00 2001 From: Anton Kalyaev Date: Fri, 3 May 2013 16:16:01 +0400 Subject: replace apostrophe with backquote for matching [ci skip] --- activesupport/lib/active_support/callbacks.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 893c2500d7..21f4125a94 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -136,7 +136,7 @@ module ActiveSupport if @_is_object_filter _filter_matches = @filter.to_s.start_with?(_method_name_for_object_filter(_kind, _filter, false)) else - _filter_matches = (@filter == _filter) + _filter_matches = (@filter == _filter) end @kind == _kind && _filter_matches @@ -198,7 +198,7 @@ module ActiveSupport # Compile around filters with conditions into proxy methods # that contain the conditions. # - # For `set_callback :save, :around, :filter_name, if: :condition': + # For `set_callback :save, :around, :filter_name, if: :condition`: # # def _conditional_callback_save_17 # if condition -- cgit v1.2.3 From 4c242e6d33237a20f272e75db620a53e4fe9c2ab Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 3 May 2013 11:29:35 -0700 Subject: Squashed commit of the following: commit 2683de5da85135e8d9fe48593ff6167db9d64b18 Author: Aaron Patterson Date: Fri May 3 11:29:20 2013 -0700 cannot support infinite ranges right now commit cebb6acef2c3957f975f6db4afd849e535126253 Author: Aaron Patterson Date: Fri May 3 11:26:12 2013 -0700 reverting infinity comparison commit 385f7e6b4efd1bf9b89e8d607fcb13e5b03737ea Author: Aaron Patterson Date: Fri May 3 11:23:28 2013 -0700 Revert "Added ability to compare date/time with infinity" This reverts commit 38f28dca3aa16efd6cc3af6453f2e6b9e9655ec1. Conflicts: activesupport/CHANGELOG.md activesupport/lib/active_support/core_ext/numeric/infinite_comparable.rb activesupport/test/core_ext/date_ext_test.rb activesupport/test/core_ext/date_time_ext_test.rb activesupport/test/core_ext/numeric_ext_test.rb activesupport/test/core_ext/time_ext_test.rb activesupport/test/core_ext/time_with_zone_test.rb commit 0d799a188dc12b18267fc8421675729917610047 Author: Aaron Patterson Date: Fri May 3 11:18:53 2013 -0700 Revert "Refactor infinite comparable definition a bit" This reverts commit dd3360e05e4909f2f0c74a624cccc2def688f828. commit 42dec90e49745bbfae546f0560b8783f6b48b074 Author: Aaron Patterson Date: Fri May 3 11:18:47 2013 -0700 Revert "Require 'active_support/core_ext/module/aliasing' in the infinite_comparable module" This reverts commit 7003e71c13c53ec3d34250560fbf80b8381df693. --- activesupport/lib/active_support/core_ext/date.rb | 1 - .../core_ext/date/infinite_comparable.rb | 5 ---- .../lib/active_support/core_ext/date_time.rb | 1 - .../core_ext/date_time/calculations.rb | 7 +++++ .../core_ext/date_time/infinite_comparable.rb | 5 ---- .../active_support/core_ext/infinite_comparable.rb | 35 ---------------------- .../lib/active_support/core_ext/numeric.rb | 1 - .../core_ext/numeric/infinite_comparable.rb | 9 ------ activesupport/lib/active_support/core_ext/time.rb | 1 - .../core_ext/time/infinite_comparable.rb | 5 ---- 10 files changed, 7 insertions(+), 63 deletions(-) delete mode 100644 activesupport/lib/active_support/core_ext/date/infinite_comparable.rb delete mode 100644 activesupport/lib/active_support/core_ext/date_time/infinite_comparable.rb delete mode 100644 activesupport/lib/active_support/core_ext/infinite_comparable.rb delete mode 100644 activesupport/lib/active_support/core_ext/numeric/infinite_comparable.rb delete mode 100644 activesupport/lib/active_support/core_ext/time/infinite_comparable.rb (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/date.rb b/activesupport/lib/active_support/core_ext/date.rb index 5f13f5f70f..465fedda80 100644 --- a/activesupport/lib/active_support/core_ext/date.rb +++ b/activesupport/lib/active_support/core_ext/date.rb @@ -2,5 +2,4 @@ require 'active_support/core_ext/date/acts_like' require 'active_support/core_ext/date/calculations' require 'active_support/core_ext/date/conversions' require 'active_support/core_ext/date/zones' -require 'active_support/core_ext/date/infinite_comparable' diff --git a/activesupport/lib/active_support/core_ext/date/infinite_comparable.rb b/activesupport/lib/active_support/core_ext/date/infinite_comparable.rb deleted file mode 100644 index ca5d793942..0000000000 --- a/activesupport/lib/active_support/core_ext/date/infinite_comparable.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'active_support/core_ext/infinite_comparable' - -class Date - include InfiniteComparable -end diff --git a/activesupport/lib/active_support/core_ext/date_time.rb b/activesupport/lib/active_support/core_ext/date_time.rb index 024af91738..e8a27b9f38 100644 --- a/activesupport/lib/active_support/core_ext/date_time.rb +++ b/activesupport/lib/active_support/core_ext/date_time.rb @@ -2,4 +2,3 @@ require 'active_support/core_ext/date_time/acts_like' require 'active_support/core_ext/date_time/calculations' require 'active_support/core_ext/date_time/conversions' require 'active_support/core_ext/date_time/zones' -require 'active_support/core_ext/date_time/infinite_comparable' diff --git a/activesupport/lib/active_support/core_ext/date_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_time/calculations.rb index f347f09293..937567440b 100644 --- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb @@ -155,4 +155,11 @@ class DateTime def utc_offset (offset * 86400).to_i end + + # Layers additional behavior on DateTime#<=> so that Time and + # ActiveSupport::TimeWithZone instances can be compared with a DateTime. + def <=>(other) + super other.to_datetime + end + end diff --git a/activesupport/lib/active_support/core_ext/date_time/infinite_comparable.rb b/activesupport/lib/active_support/core_ext/date_time/infinite_comparable.rb deleted file mode 100644 index 8a282b19f2..0000000000 --- a/activesupport/lib/active_support/core_ext/date_time/infinite_comparable.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'active_support/core_ext/infinite_comparable' - -class DateTime - include InfiniteComparable -end diff --git a/activesupport/lib/active_support/core_ext/infinite_comparable.rb b/activesupport/lib/active_support/core_ext/infinite_comparable.rb deleted file mode 100644 index b78b2deaad..0000000000 --- a/activesupport/lib/active_support/core_ext/infinite_comparable.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'active_support/concern' -require 'active_support/core_ext/module/aliasing' -require 'active_support/core_ext/object/try' - -module InfiniteComparable - extend ActiveSupport::Concern - - included do - alias_method_chain :<=>, :infinity - end - - define_method :'<=>_with_infinity' do |other| - if other.class == self.class - public_send :'<=>_without_infinity', other - else - infinite = try(:infinite?) - other_infinite = other.try(:infinite?) - - # inf <=> inf - if infinite && other_infinite - infinite <=> other_infinite - # not_inf <=> inf - elsif other_infinite - -other_infinite - # inf <=> not_inf - elsif infinite - infinite - else - conversion = "to_#{self.class.name.downcase}" - other = other.public_send(conversion) if other.respond_to?(conversion) - public_send :'<=>_without_infinity', other - end - end - end -end diff --git a/activesupport/lib/active_support/core_ext/numeric.rb b/activesupport/lib/active_support/core_ext/numeric.rb index d5cfc2ece4..a6bc0624be 100644 --- a/activesupport/lib/active_support/core_ext/numeric.rb +++ b/activesupport/lib/active_support/core_ext/numeric.rb @@ -1,4 +1,3 @@ require 'active_support/core_ext/numeric/bytes' require 'active_support/core_ext/numeric/time' require 'active_support/core_ext/numeric/conversions' -require 'active_support/core_ext/numeric/infinite_comparable' diff --git a/activesupport/lib/active_support/core_ext/numeric/infinite_comparable.rb b/activesupport/lib/active_support/core_ext/numeric/infinite_comparable.rb deleted file mode 100644 index b5f1b0487b..0000000000 --- a/activesupport/lib/active_support/core_ext/numeric/infinite_comparable.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'active_support/core_ext/infinite_comparable' - -class Float - include InfiniteComparable -end - -class BigDecimal - include InfiniteComparable -end diff --git a/activesupport/lib/active_support/core_ext/time.rb b/activesupport/lib/active_support/core_ext/time.rb index af6b589b71..32cffe237d 100644 --- a/activesupport/lib/active_support/core_ext/time.rb +++ b/activesupport/lib/active_support/core_ext/time.rb @@ -3,4 +3,3 @@ require 'active_support/core_ext/time/calculations' require 'active_support/core_ext/time/conversions' require 'active_support/core_ext/time/marshal' require 'active_support/core_ext/time/zones' -require 'active_support/core_ext/time/infinite_comparable' diff --git a/activesupport/lib/active_support/core_ext/time/infinite_comparable.rb b/activesupport/lib/active_support/core_ext/time/infinite_comparable.rb deleted file mode 100644 index 63795885f5..0000000000 --- a/activesupport/lib/active_support/core_ext/time/infinite_comparable.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'active_support/core_ext/infinite_comparable' - -class Time - include InfiniteComparable -end -- cgit v1.2.3 From 41fbfb40d89e76af8e47093237039a9887541612 Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Sat, 4 May 2013 00:24:34 +0530 Subject: use destructive sort on array in Hash#to_param for performance gains. Check https://gist.github.com/vipulnsward/6aad158c06a22f931a71 to see the gains. --- activesupport/lib/active_support/core_ext/object/to_param.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/object/to_param.rb b/activesupport/lib/active_support/core_ext/object/to_param.rb index 0d5f3501e5..3b137ce6ae 100644 --- a/activesupport/lib/active_support/core_ext/object/to_param.rb +++ b/activesupport/lib/active_support/core_ext/object/to_param.rb @@ -53,6 +53,6 @@ class Hash def to_param(namespace = nil) collect do |key, value| value.to_query(namespace ? "#{namespace}[#{key}]" : key) - end.sort * '&' + end.sort! * '&' end end -- cgit v1.2.3 From 36d41a15c35e6f4b698931987b2115e221d0fcfa Mon Sep 17 00:00:00 2001 From: Daniel Schierbeck Date: Mon, 15 Apr 2013 16:41:27 +0200 Subject: Allow fetching multiple values from the cache at once Add a simple API for fetching a list of entries from the cache, where any missing entries are computed by a supplied block. --- activesupport/lib/active_support/cache.rb | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 6c220ae625..b1ab5570a8 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -352,6 +352,34 @@ module ActiveSupport results end + # Fetches data from the cache, using the given keys. If there is data in + # the cache with the given keys, then that data is returned. Otherwise, + # the supplied block is called for each key for which there was no data, + # and the result will be written to the cache and returned. + # + # Options are passed to the underlying cache implementation. + # + # Returns an array with the data for each of the names. For example: + # + # cache.write("bim", "bam") + # cache.fetch_multi("bim", "boom") {|key| key * 2 } + # #=> ["bam", "boomboom"] + # + def fetch_multi(*names) + options = names.extract_options! + options = merged_options(options) + + results = read_multi(*names, options) + + names.map do |name| + results.fetch(name) do + value = yield name + write(name, value, options) + value + end + end + end + # Writes the value to the cache, with the key. # # Options are passed to the underlying cache implementation. -- cgit v1.2.3 From 3073c531983de243219fb55be93fbcebfdd9c44e Mon Sep 17 00:00:00 2001 From: Ryan Davis Date: Mon, 6 May 2013 17:38:45 -0700 Subject: Updates to make rails 4 happy with minitest 5: + Namespace changes, overhaul of runners. + Internal ivar name changes - Removed a logger globally applied to tests that spew everywhere?!? + Override Minitest#__run to sort tests by name. + Reworked testing isolation to work with the new cleaner architecture. - Removed a bunch of tests that just test minitest straight up. I think these changes were all merged to minitest 4 a long time ago. - Minor report output differences. --- activesupport/lib/active_support/test_case.rb | 24 +++++++++++++++++++--- .../lib/active_support/testing/autorun.rb | 4 ++-- .../lib/active_support/testing/isolation.rb | 17 ++++++--------- .../lib/active_support/testing/tagged_logging.rb | 2 +- 4 files changed, 30 insertions(+), 17 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb index 8b392c36d0..f0962998a0 100644 --- a/activesupport/lib/active_support/test_case.rb +++ b/activesupport/lib/active_support/test_case.rb @@ -16,10 +16,28 @@ begin rescue LoadError end +module Minitest # :nodoc: + class << self + remove_method :__run + end + + def self.__run reporter, options # :nodoc: + # FIXME: MT5's runnables is not ordered. This is needed because + # we have have tests have cross-class order-dependent bugs. + suites = Runnable.runnables.sort_by { |ts| ts.name.to_s } + + parallel, serial = suites.partition { |s| s.test_order == :parallel } + + ParallelEach.new(parallel).map { |suite| suite.run reporter, options } + + serial.map { |suite| suite.run reporter, options } + end +end + module ActiveSupport - class TestCase < ::MiniTest::Unit::TestCase - Assertion = MiniTest::Assertion - alias_method :method_name, :__name__ + class TestCase < ::Minitest::Test + Assertion = Minitest::Assertion + + alias_method :method_name, :name $tags = {} def self.for_tag(tag) diff --git a/activesupport/lib/active_support/testing/autorun.rb b/activesupport/lib/active_support/testing/autorun.rb index c446adc16d..45d8193abb 100644 --- a/activesupport/lib/active_support/testing/autorun.rb +++ b/activesupport/lib/active_support/testing/autorun.rb @@ -1,5 +1,5 @@ gem 'minitest' -require 'minitest/unit' +require 'minitest/autorun' -MiniTest::Unit.autorun +Minitest.autorun diff --git a/activesupport/lib/active_support/testing/isolation.rb b/activesupport/lib/active_support/testing/isolation.rb index e16b73a036..9c52ae7768 100644 --- a/activesupport/lib/active_support/testing/isolation.rb +++ b/activesupport/lib/active_support/testing/isolation.rb @@ -72,16 +72,12 @@ module ActiveSupport end end - def run(runner) - _run_class_setup - - serialized = run_in_isolation do |isolated_runner| - super(isolated_runner) + def run + serialized = run_in_isolation do + super end - retval, proxy = Marshal.load(serialized) - proxy.__replay__(runner) - retval + Marshal.load(serialized) end module Forking @@ -90,9 +86,8 @@ module ActiveSupport pid = fork do read.close - proxy = ProxyTestResult.new - retval = yield proxy - write.puts [Marshal.dump([retval, proxy])].pack("m") + yield + write.puts [Marshal.dump(self.dup)].pack("m") exit! end diff --git a/activesupport/lib/active_support/testing/tagged_logging.rb b/activesupport/lib/active_support/testing/tagged_logging.rb index 9d43eb179f..f4cee64091 100644 --- a/activesupport/lib/active_support/testing/tagged_logging.rb +++ b/activesupport/lib/active_support/testing/tagged_logging.rb @@ -7,7 +7,7 @@ module ActiveSupport def before_setup if tagged_logger - heading = "#{self.class}: #{__name__}" + heading = "#{self.class}: #{name}" divider = '-' * heading.size tagged_logger.info divider tagged_logger.info heading -- cgit v1.2.3 From 9003a422f2a717ef11409245bfb8e81018be56c4 Mon Sep 17 00:00:00 2001 From: Sean Walbran Date: Tue, 7 May 2013 13:22:52 -0500 Subject: fix issue #10502, do not recompute method name for already-stringified object filter --- activesupport/lib/active_support/callbacks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 893c2500d7..1dcacf0b12 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -133,7 +133,7 @@ module ActiveSupport end def matches?(_kind, _filter) - if @_is_object_filter + if @_is_object_filter && !_filter.is_a?(String) _filter_matches = @filter.to_s.start_with?(_method_name_for_object_filter(_kind, _filter, false)) else _filter_matches = (@filter == _filter) -- cgit v1.2.3 From c3a5ea6ef696467acebaae4fc003662124ab26e6 Mon Sep 17 00:00:00 2001 From: aditya-kapoor Date: Wed, 8 May 2013 15:51:04 +0530 Subject: Changed spelling of Busines to Business --- activesupport/lib/active_support/core_ext/string/inflections.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb index 0b506a6030..56e8a5f98d 100644 --- a/activesupport/lib/active_support/core_ext/string/inflections.rb +++ b/activesupport/lib/active_support/core_ext/string/inflections.rb @@ -185,7 +185,7 @@ class String # # Singular names are not handled correctly. # - # 'business'.classify # => "Busines" + # 'business'.classify # => "Business" def classify ActiveSupport::Inflector.classify(self) end -- cgit v1.2.3 From 4de7442f450462c2d3322abec898862a37e8925a Mon Sep 17 00:00:00 2001 From: Tomohiko Himura Date: Thu, 9 May 2013 00:41:00 +0900 Subject: dependency ActiveSupport::Deprecation --- activesupport/lib/active_support/core_ext/hash/diff.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/hash/diff.rb b/activesupport/lib/active_support/core_ext/hash/diff.rb index 5f3868b5b0..4359213380 100644 --- a/activesupport/lib/active_support/core_ext/hash/diff.rb +++ b/activesupport/lib/active_support/core_ext/hash/diff.rb @@ -1,3 +1,5 @@ +require 'active_support/deprecation' + class Hash # Returns a hash that represents the difference between two hashes. # -- cgit v1.2.3 From 738dbc0b3955531345354475adc990e4a273bba8 Mon Sep 17 00:00:00 2001 From: Burke Libbey Date: Thu, 25 Apr 2013 20:43:54 -0500 Subject: Use ruby's Encoding support for tidy_bytes The previous implementation was quite slow. This leverages some of the transcoding abilities built into Ruby 1.9 instead. It is roughly 96% faster. The roundtrip through UTF_8_MAC here is because ruby won't let you transcode from UTF_8 to UTF_8. I chose the closest encoding I could find as an intermediate. --- .../lib/active_support/multibyte/unicode.rb | 58 +++++++--------------- 1 file changed, 19 insertions(+), 39 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/multibyte/unicode.rb b/activesupport/lib/active_support/multibyte/unicode.rb index cbc1608349..f1dfff738c 100644 --- a/activesupport/lib/active_support/multibyte/unicode.rb +++ b/activesupport/lib/active_support/multibyte/unicode.rb @@ -218,51 +218,31 @@ module ActiveSupport # Passing +true+ will forcibly tidy all bytes, assuming that the string's # encoding is entirely CP1252 or ISO-8859-1. def tidy_bytes(string, force = false) + return string if string.empty? + if force - return string.unpack("C*").map do |b| - tidy_byte(b) - end.flatten.compact.pack("C*").unpack("U*").pack("U*") + return string.encode(Encoding::UTF_8, Encoding::Windows_1252, invalid: :replace, undef: :replace) end - bytes = string.unpack("C*") - conts_expected = 0 - last_lead = 0 - - bytes.each_index do |i| + # We can't transcode to the same format, so we choose a nearly-identical encoding. + # We're going to 'transcode' bytes from UTF-8 when possible, then fall back to + # CP1252 when we get errors. The final string will be 'converted' back to UTF-8 + # before returning. + reader = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_8_MAC) - byte = bytes[i] - is_cont = byte > 127 && byte < 192 - is_lead = byte > 191 && byte < 245 - is_unused = byte > 240 - is_restricted = byte > 244 + source = string.dup + out = ''.force_encoding(Encoding::UTF_8_MAC) - # Impossible or highly unlikely byte? Clean it. - if is_unused || is_restricted - bytes[i] = tidy_byte(byte) - elsif is_cont - # Not expecting continuation byte? Clean up. Otherwise, now expect one less. - conts_expected == 0 ? bytes[i] = tidy_byte(byte) : conts_expected -= 1 - else - if conts_expected > 0 - # Expected continuation, but got ASCII or leading? Clean backwards up to - # the leading byte. - (1..(i - last_lead)).each {|j| bytes[i - j] = tidy_byte(bytes[i - j])} - conts_expected = 0 - end - if is_lead - # Final byte is leading? Clean it. - if i == bytes.length - 1 - bytes[i] = tidy_byte(bytes.last) - else - # Valid leading byte? Expect continuations determined by position of - # first zero bit, with max of 3. - conts_expected = byte < 224 ? 1 : byte < 240 ? 2 : 3 - last_lead = i - end - end - end + loop do + reader.primitive_convert(source, out) + _, _, _, error_bytes, _ = reader.primitive_errinfo + break if error_bytes.nil? + out << error_bytes.encode(Encoding::UTF_8_MAC, Encoding::Windows_1252, invalid: :replace, undef: :replace) end - bytes.empty? ? "" : bytes.flatten.compact.pack("C*").unpack("U*").pack("U*") + + reader.finish + + out.encode!(Encoding::UTF_8) end # Returns the KC normalization of the string by default. NFKC is -- cgit v1.2.3 From b9903c398eda827729160b1653aff4e8dbba8121 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 7 May 2013 13:26:23 -0700 Subject: polymorphic comparison operator --- activesupport/lib/active_support/callbacks.rb | 35 ++++++++++++++++++--------- 1 file changed, 24 insertions(+), 11 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 1dcacf0b12..9c330d9e2d 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -91,6 +91,28 @@ module ActiveSupport class Callback #:nodoc:# @@_callback_sequence = 0 + class Basic < Callback + def matches?(_kind, _filter) + super && @filter == _filter + end + end + + class Object < Callback + def matches?(_kind, _filter) + super && @filter.to_s.start_with?(_method_name_for_object_filter(_kind, _filter, false)) + end + end + + def self.build(chain, filter, kind, options, _klass) + klass = case filter + when Array, Symbol, String, Proc + Callback::Basic + else + Callback::Object + end + klass.new chain, filter, kind, options, _klass + end + attr_accessor :chain, :filter, :kind, :options, :klass, :raw_filter def initialize(chain, filter, kind, options, klass) @@ -133,13 +155,7 @@ module ActiveSupport end def matches?(_kind, _filter) - if @_is_object_filter && !_filter.is_a?(String) - _filter_matches = @filter.to_s.start_with?(_method_name_for_object_filter(_kind, _filter, false)) - else - _filter_matches = (@filter == _filter) - end - - @kind == _kind && _filter_matches + @kind == _kind end def duplicates?(other) @@ -273,8 +289,6 @@ module ActiveSupport # a method is created that calls the before_foo method # on the object. def _compile_filter(filter) - @_is_object_filter = false - case filter when Array filter.map {|f| _compile_filter(f)} @@ -290,7 +304,6 @@ module ActiveSupport method_name << (filter.arity == 1 ? "(self)" : " self, Proc.new ") else method_name = _method_name_for_object_filter(kind, filter) - @_is_object_filter = true @klass.send(:define_method, "#{method_name}_object") { filter } _normalize_legacy_filter(kind, filter) @@ -465,7 +478,7 @@ module ActiveSupport __update_callbacks(name, filter_list, block) do |target, chain, type, filters, options| mapped ||= filters.map do |filter| - Callback.new(chain, filter, type, options.dup, self) + Callback.build(chain, filter, type, options.dup, self) end options[:prepend] ? chain.prepend(*mapped) : chain.append(*mapped) -- cgit v1.2.3 From f21da67aab6ad4acc2f11a1eaf800444e3b0fe21 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 7 May 2013 16:15:49 -0700 Subject: fix object comparison case --- activesupport/lib/active_support/callbacks.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 9c330d9e2d..689c05ded4 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -99,7 +99,11 @@ module ActiveSupport class Object < Callback def matches?(_kind, _filter) - super && @filter.to_s.start_with?(_method_name_for_object_filter(_kind, _filter, false)) + if !_filter.is_a?(String) + super && @filter.to_s.start_with?(_method_name_for_object_filter(_kind, _filter, false)) + else + super && @filter == _filter + end end end -- cgit v1.2.3 From 6abbc4a5884a109052fe46d886895ec476766519 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 7 May 2013 16:19:31 -0700 Subject: if the callbacks are not the same class, they cannot be duplicates --- activesupport/lib/active_support/callbacks.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 689c05ded4..0548284186 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -99,10 +99,12 @@ module ActiveSupport class Object < Callback def matches?(_kind, _filter) + return false unless super + if !_filter.is_a?(String) - super && @filter.to_s.start_with?(_method_name_for_object_filter(_kind, _filter, false)) + @filter.to_s.start_with?(_method_name_for_object_filter(_kind, _filter, false)) else - super && @filter == _filter + @filter == _filter end end end @@ -163,6 +165,8 @@ module ActiveSupport end def duplicates?(other) + return false unless self.class == other.class + matches?(other.kind, other.filter) end -- cgit v1.2.3 From 8038f7eb10e0168a0f438d443ab69d61cb396ef5 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 May 2013 12:01:55 -0700 Subject: separate filters from source code --- activesupport/lib/active_support/callbacks.rb | 51 ++++++++++++++++----------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 0548284186..96cf0d5654 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -92,20 +92,11 @@ module ActiveSupport @@_callback_sequence = 0 class Basic < Callback - def matches?(_kind, _filter) - super && @filter == _filter - end end class Object < Callback - def matches?(_kind, _filter) - return false unless super - - if !_filter.is_a?(String) - @filter.to_s.start_with?(_method_name_for_object_filter(_kind, _filter, false)) - else - @filter == _filter - end + def duplicates?(other) + false end end @@ -127,7 +118,8 @@ module ActiveSupport normalize_options!(options) @raw_filter, @options = filter, options - @filter = _compile_filter(filter) + @filter = _compile_filter(filter) + @source = _compile_source(filter) recompile_options! end @@ -161,7 +153,7 @@ module ActiveSupport end def matches?(_kind, _filter) - @kind == _kind + @kind == _kind && filter == _filter end def duplicates?(other) @@ -191,7 +183,7 @@ module ActiveSupport # This double assignment is to prevent warnings in 1.9.3 as # the `result` variable is not always used except if the # terminator code refers to it. - result = result = #{@filter} + result = result = #{@source} halted = (#{chain.config[:terminator]}) if halted halted_callback_hook(#{@raw_filter.inspect.inspect}) @@ -203,7 +195,7 @@ module ActiveSupport <<-RUBY_EVAL #{code} if #{!chain.config[:skip_after_callbacks_if_terminated] || "!halted"} && #{@compiled_options} - #{@filter} + #{@source} end RUBY_EVAL when :around @@ -238,7 +230,7 @@ module ActiveSupport @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 def #{name}(halted) if #{@compiled_options} && !halted - #{@filter} do + #{@source} do yield self end else @@ -256,11 +248,11 @@ module ActiveSupport conditions = ["true"] unless options[:if].empty? - conditions << Array(_compile_filter(options[:if])) + conditions << Array(_compile_source(options[:if])) end unless options[:unless].empty? - conditions << Array(_compile_filter(options[:unless])).map {|f| "!#{f}"} + conditions << Array(_compile_source(options[:unless])).map {|f| "!#{f}"} end @compiled_options = conditions.flatten.join(" && ") @@ -276,6 +268,25 @@ module ActiveSupport method_name end + def _compile_filter(filter) + case filter + when Array + filter.map {|f| _compile_filter(f)} + when Symbol + filter + when String + "(#{filter})" + when Proc + method_name = "_callback_#{@kind}_#{next_id}" + @klass.send(:define_method, method_name, &filter) + return method_name if filter.arity <= 0 + + method_name << (filter.arity == 1 ? "(self)" : " self, Proc.new ") + else + filter + end + end + # Filters support: # # Arrays:: Used in conditions. This is used to specify @@ -296,10 +307,10 @@ module ActiveSupport # Objects:: # a method is created that calls the before_foo method # on the object. - def _compile_filter(filter) + def _compile_source(filter) case filter when Array - filter.map {|f| _compile_filter(f)} + filter.map {|f| _compile_source(f)} when Symbol filter when String -- cgit v1.2.3 From 9e323e7dabcab2a16e6f91ffa8152f66a9534fe1 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 May 2013 13:36:04 -0700 Subject: separate identification computation --- activesupport/lib/active_support/callbacks.rb | 42 ++++++++++++--------------- 1 file changed, 18 insertions(+), 24 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 96cf0d5654..ee4b3fe6bb 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -102,7 +102,7 @@ module ActiveSupport def self.build(chain, filter, kind, options, _klass) klass = case filter - when Array, Symbol, String, Proc + when Array, Symbol, String Callback::Basic else Callback::Object @@ -110,7 +110,7 @@ module ActiveSupport klass.new chain, filter, kind, options, _klass end - attr_accessor :chain, :filter, :kind, :options, :klass, :raw_filter + attr_accessor :chain, :kind, :options, :klass, :raw_filter def initialize(chain, filter, kind, options, klass) @chain, @kind, @klass = chain, kind, klass @@ -118,11 +118,15 @@ module ActiveSupport normalize_options!(options) @raw_filter, @options = filter, options - @filter = _compile_filter(filter) + @key = compute_identifier filter @source = _compile_source(filter) recompile_options! end + def filter + @key + end + def deprecate_per_key_option(options) if options[:per_key] raise NotImplementedError, ":per_key option is no longer supported. Use generic :if and :unless options instead." @@ -211,6 +215,15 @@ module ActiveSupport private + def compute_identifier(filter) + case filter + when String, ::Proc + filter.object_id + else + filter + end + end + # Compile around filters with conditions into proxy methods # that contain the conditions. # @@ -268,25 +281,6 @@ module ActiveSupport method_name end - def _compile_filter(filter) - case filter - when Array - filter.map {|f| _compile_filter(f)} - when Symbol - filter - when String - "(#{filter})" - when Proc - method_name = "_callback_#{@kind}_#{next_id}" - @klass.send(:define_method, method_name, &filter) - return method_name if filter.arity <= 0 - - method_name << (filter.arity == 1 ? "(self)" : " self, Proc.new ") - else - filter - end - end - # Filters support: # # Arrays:: Used in conditions. This is used to specify @@ -315,12 +309,12 @@ module ActiveSupport filter when String "(#{filter})" - when Proc + when ::Proc method_name = "_callback_#{@kind}_#{next_id}" @klass.send(:define_method, method_name, &filter) return method_name if filter.arity <= 0 - method_name << (filter.arity == 1 ? "(self)" : " self, Proc.new ") + method_name << (filter.arity == 1 ? "(self)" : " self, ::Proc.new ") else method_name = _method_name_for_object_filter(kind, filter) @klass.send(:define_method, "#{method_name}_object") { filter } -- cgit v1.2.3 From ece76f3840fb0327e58f91d6091beb66801deaed Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 May 2013 14:35:43 -0700 Subject: adding tests for lambdas as conditions --- activesupport/lib/active_support/callbacks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index ee4b3fe6bb..e948314be7 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -314,7 +314,7 @@ module ActiveSupport @klass.send(:define_method, method_name, &filter) return method_name if filter.arity <= 0 - method_name << (filter.arity == 1 ? "(self)" : " self, ::Proc.new ") + method_name << (filter.arity == 1 ? "(self)" : "(self, ::Proc.new)") else method_name = _method_name_for_object_filter(kind, filter) @klass.send(:define_method, "#{method_name}_object") { filter } -- cgit v1.2.3 From fe7f4b4bba4addfe2bbcb32fa67a6d9930811386 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 May 2013 15:23:54 -0700 Subject: using strings as scopes is not used anywhere, so remove it --- activesupport/lib/active_support/callbacks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index e948314be7..666126d199 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -321,7 +321,7 @@ module ActiveSupport _normalize_legacy_filter(kind, filter) scopes = Array(chain.config[:scope]) - method_to_call = scopes.map{ |s| s.is_a?(Symbol) ? send(s) : s }.join("_") + method_to_call = scopes.map{ |s| send(s) }.join("_") @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 def #{method_name}(&blk) -- cgit v1.2.3 From 05609f472912cc841d99e3b0adb18c4f3d0eb9ae Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 May 2013 16:25:43 -0700 Subject: use public send on the scope parameters --- activesupport/lib/active_support/callbacks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 666126d199..6fe7e0f4fb 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -321,7 +321,7 @@ module ActiveSupport _normalize_legacy_filter(kind, filter) scopes = Array(chain.config[:scope]) - method_to_call = scopes.map{ |s| send(s) }.join("_") + method_to_call = scopes.map{ |s| public_send(s) }.join("_") @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 def #{method_name}(&blk) -- cgit v1.2.3 From 1a4d8736ce7294d2ecfc46172cc8de3b4591ac23 Mon Sep 17 00:00:00 2001 From: Waseem Ahmad Date: Thu, 9 May 2013 12:32:02 +0530 Subject: Require different core extensions correctly. The begin rescue block is specifically to catch LoadError while loading i18n gem. Other core extensions, under active support, should be required outside of the begin rescue block. --- activesupport/lib/active_support/i18n.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/i18n.rb b/activesupport/lib/active_support/i18n.rb index 22521a8e93..6cc98191d4 100644 --- a/activesupport/lib/active_support/i18n.rb +++ b/activesupport/lib/active_support/i18n.rb @@ -1,13 +1,13 @@ +require 'active_support/core_ext/hash/deep_merge' +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/hash/slice' begin - require 'active_support/core_ext/hash/deep_merge' - require 'active_support/core_ext/hash/except' - require 'active_support/core_ext/hash/slice' require 'i18n' - require 'active_support/lazy_load_hooks' rescue LoadError => e $stderr.puts "The i18n gem is not available. Please add it to your Gemfile and run bundle install" raise e end +require 'active_support/lazy_load_hooks' ActiveSupport.run_load_hooks(:i18n) I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml" -- cgit v1.2.3 From de4dcacc200f9bfa79f3c2e13b2091e3d5262f6d Mon Sep 17 00:00:00 2001 From: Ryan Davis Date: Thu, 9 May 2013 01:50:56 -0700 Subject: oops. I should have only required minitest, not minitets/autorun. muscle memory. --- activesupport/lib/active_support/testing/autorun.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/testing/autorun.rb b/activesupport/lib/active_support/testing/autorun.rb index 45d8193abb..5aa5f46310 100644 --- a/activesupport/lib/active_support/testing/autorun.rb +++ b/activesupport/lib/active_support/testing/autorun.rb @@ -1,5 +1,5 @@ gem 'minitest' -require 'minitest/autorun' +require 'minitest' Minitest.autorun -- cgit v1.2.3 From 39b8b8fdbf6c175a64f07198ff1c950e33c72cd0 Mon Sep 17 00:00:00 2001 From: Prathamesh Sonpatki Date: Thu, 9 May 2013 17:27:08 +0530 Subject: rails -> Rails [ci skip] --- activesupport/lib/active_support/key_generator.rb | 2 +- activesupport/lib/active_support/lazy_load_hooks.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/key_generator.rb b/activesupport/lib/active_support/key_generator.rb index 37124fb7ae..598c46bce5 100644 --- a/activesupport/lib/active_support/key_generator.rb +++ b/activesupport/lib/active_support/key_generator.rb @@ -4,7 +4,7 @@ require 'openssl' module ActiveSupport # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2 # It can be used to derive a number of keys for various purposes from a given secret. - # This lets rails applications have a single secure secret, but avoid reusing that + # This lets Rails applications have a single secure secret, but avoid reusing that # key in multiple incompatible contexts. class KeyGenerator def initialize(secret, options = {}) diff --git a/activesupport/lib/active_support/lazy_load_hooks.rb b/activesupport/lib/active_support/lazy_load_hooks.rb index e489512531..e2b8f0f648 100644 --- a/activesupport/lib/active_support/lazy_load_hooks.rb +++ b/activesupport/lib/active_support/lazy_load_hooks.rb @@ -1,5 +1,5 @@ module ActiveSupport - # lazy_load_hooks allows rails to lazily load a lot of components and thus + # lazy_load_hooks allows Rails to lazily load a lot of components and thus # making the app boot faster. Because of this feature now there is no need to # require ActiveRecord::Base at boot time purely to apply # configuration. Instead a hook is registered that applies configuration once -- cgit v1.2.3 From 582b44175b627e3578fe71e1d452c429022da636 Mon Sep 17 00:00:00 2001 From: Mario Caropreso Date: Thu, 9 May 2013 13:41:56 +0100 Subject: Added escaping of U+2028 and U+2029 inside the json encoder. U+2028 and U+2029 are allowed inside strings in JSON (as all literal Unicode characters) but JavaScript defines them as newline seperators. Because no literal newlines are allowed in a string, this causes a ParseError in the browser. We work around this issue by replacing them with the escaped version. The resulting JSON is still valid and can be parsed in the browser. This commit has been coauthored with Viktor Kelemen @yikulju --- activesupport/lib/active_support/json/encoding.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index 9bf1ea35b3..db05b09a66 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -104,7 +104,10 @@ module ActiveSupport '\\' => '\\\\', '>' => '\u003E', '<' => '\u003C', - '&' => '\u0026' } + '&' => '\u0026', + "#{0xe2.chr}#{0x80.chr}#{0xa8.chr}" => '\u2028', + "#{0xe2.chr}#{0x80.chr}#{0xa9.chr}" => '\u2029', + } class << self # If true, use ISO 8601 format for dates and times. Otherwise, fall back @@ -121,9 +124,9 @@ module ActiveSupport def escape_html_entities_in_json=(value) self.escape_regex = \ if @escape_html_entities_in_json = value - /[\x00-\x1F"\\><&]/ + /[\x00-\x1F"\\><&]|#{0xe2.chr}#{0x80.chr}#{0xa8.chr}|#{0xe2.chr}#{0x80.chr}#{0xa9.chr}/ else - /[\x00-\x1F"\\]/ + /[\x00-\x1F"\\]|#{0xe2.chr}#{0x80.chr}#{0xa8.chr}|#{0xe2.chr}#{0x80.chr}#{0xa9.chr}/ end end -- cgit v1.2.3 From e6cebce48cdd0cffec1a4e85b76108c3a9f4968f Mon Sep 17 00:00:00 2001 From: aditya-kapoor Date: Thu, 9 May 2013 23:27:15 +0530 Subject: changed rails -> Rails at two places --- activesupport/lib/active_support/key_generator.rb | 2 +- activesupport/lib/active_support/lazy_load_hooks.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/key_generator.rb b/activesupport/lib/active_support/key_generator.rb index 37124fb7ae..598c46bce5 100644 --- a/activesupport/lib/active_support/key_generator.rb +++ b/activesupport/lib/active_support/key_generator.rb @@ -4,7 +4,7 @@ require 'openssl' module ActiveSupport # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2 # It can be used to derive a number of keys for various purposes from a given secret. - # This lets rails applications have a single secure secret, but avoid reusing that + # This lets Rails applications have a single secure secret, but avoid reusing that # key in multiple incompatible contexts. class KeyGenerator def initialize(secret, options = {}) diff --git a/activesupport/lib/active_support/lazy_load_hooks.rb b/activesupport/lib/active_support/lazy_load_hooks.rb index e489512531..e2b8f0f648 100644 --- a/activesupport/lib/active_support/lazy_load_hooks.rb +++ b/activesupport/lib/active_support/lazy_load_hooks.rb @@ -1,5 +1,5 @@ module ActiveSupport - # lazy_load_hooks allows rails to lazily load a lot of components and thus + # lazy_load_hooks allows Rails to lazily load a lot of components and thus # making the app boot faster. Because of this feature now there is no need to # require ActiveRecord::Base at boot time purely to apply # configuration. Instead a hook is registered that applies configuration once -- cgit v1.2.3 From 6189e2714b730d4ae0da11884b8082cbee0fb44c Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 May 2013 14:23:10 -0700 Subject: conditions in callbacks return consistent lambdas --- activesupport/lib/active_support/callbacks.rb | 52 ++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 9 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 6fe7e0f4fb..d998747162 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -183,7 +183,7 @@ module ActiveSupport case @kind when :before <<-RUBY_EVAL - if !halted && #{@compiled_options} + if !halted && #{@compiled_options}(value) # This double assignment is to prevent warnings in 1.9.3 as # the `result` variable is not always used except if the # terminator code refers to it. @@ -198,14 +198,14 @@ module ActiveSupport when :after <<-RUBY_EVAL #{code} - if #{!chain.config[:skip_after_callbacks_if_terminated] || "!halted"} && #{@compiled_options} + if #{!chain.config[:skip_after_callbacks_if_terminated] || "!halted"} && #{@compiled_options}(value) #{@source} end RUBY_EVAL when :around name = define_conditional_callback <<-RUBY_EVAL - #{name}(halted) do + #{name}(halted, value) do #{code} value end @@ -241,8 +241,8 @@ module ActiveSupport def define_conditional_callback name = "_conditional_callback_#{@kind}_#{next_id}" @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def #{name}(halted) - if #{@compiled_options} && !halted + def #{name}(halted, value) + if #{@compiled_options}(value) && !halted #{@source} do yield self end @@ -258,17 +258,24 @@ module ActiveSupport # symbols, string, procs, and objects), so compile a conditional # expression based on the options. def recompile_options! - conditions = ["true"] + conditions = [] unless options[:if].empty? - conditions << Array(_compile_source(options[:if])) + conditions.concat Array(_compile_options(options[:if])) end unless options[:unless].empty? - conditions << Array(_compile_source(options[:unless])).map {|f| "!#{f}"} + conditions.concat Array(_compile_options(options[:unless])).map { |f| + lambda { |*args,&blk| !f.call(*args, &blk) } + } end - @compiled_options = conditions.flatten.join(" && ") + method_name = "_callback_#{@kind}_#{next_id}" + @klass.send(:define_method, method_name) do |*args,&block| + conditions.all? { |c| c.call(self, *args, &block) } + end + + @compiled_options = method_name end def _method_name_for_object_filter(kind, filter, append_next_id = true) @@ -333,6 +340,33 @@ module ActiveSupport end end + def _compile_options(filter) + case filter + when Array + filter.map {|f| _compile_options(f)} + when Symbol + lambda { |target, value| target.send filter } + when String + l = eval "lambda { |value| #{filter} }" + lambda { |target,value| target.instance_exec(value, &l) } + when ::Proc + method_name = "_callback_#{@kind}_#{next_id}" + @klass.send(:define_method, method_name, &filter) + + if filter.arity <= 0 + return lambda { |target, _| target.instance_exec(&filter) } + end + + if filter.arity == 1 + lambda { |target, _| target.send method_name, target } + else + lambda { |target, _,&blk| target.send method_name, target, &blk } + end + else + raise + end + end + def _normalize_legacy_filter(kind, filter) if !filter.respond_to?(kind) && filter.respond_to?(:filter) message = "Filter object with #filter method is deprecated. Define method corresponding " \ -- cgit v1.2.3 From 2b1500d69597ecd0ff914dea1fbc265669abdbee Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 May 2013 17:11:12 -0700 Subject: wrap all options in lambas --- activesupport/lib/active_support/callbacks.rb | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index d998747162..0c550cced5 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -345,25 +345,31 @@ module ActiveSupport when Array filter.map {|f| _compile_options(f)} when Symbol - lambda { |target, value| target.send filter } + lambda { |target, value| target.public_send filter } when String l = eval "lambda { |value| #{filter} }" lambda { |target,value| target.instance_exec(value, &l) } when ::Proc - method_name = "_callback_#{@kind}_#{next_id}" - @klass.send(:define_method, method_name, &filter) - if filter.arity <= 0 return lambda { |target, _| target.instance_exec(&filter) } end if filter.arity == 1 - lambda { |target, _| target.send method_name, target } + lambda { |target, _| + target.instance_exec(target, &filter) + } else - lambda { |target, _,&blk| target.send method_name, target, &blk } + lambda { |target, _| + target.instance_exec target, ::Proc.new, &filter + } end else - raise + scopes = Array(chain.config[:scope]) + method_to_call = scopes.map{ |s| public_send(s) }.join("_") + + lambda { |target, _, &blk| + filter.public_send method_to_call, target, &blk + } end end -- cgit v1.2.3 From 07da9603feb445431e2d2707ca5b1798c7f86e3f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 May 2013 17:51:08 -0700 Subject: using lambas for the callback bodies --- activesupport/lib/active_support/callbacks.rb | 44 ++++++++------------------- 1 file changed, 12 insertions(+), 32 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 0c550cced5..abbb5956d0 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -187,7 +187,7 @@ module ActiveSupport # This double assignment is to prevent warnings in 1.9.3 as # the `result` variable is not always used except if the # terminator code refers to it. - result = result = #{@source} + result = result = #{@source}(value) halted = (#{chain.config[:terminator]}) if halted halted_callback_hook(#{@raw_filter.inspect.inspect}) @@ -199,7 +199,7 @@ module ActiveSupport <<-RUBY_EVAL #{code} if #{!chain.config[:skip_after_callbacks_if_terminated] || "!halted"} && #{@compiled_options}(value) - #{@source} + #{@source}(value) end RUBY_EVAL when :around @@ -243,7 +243,7 @@ module ActiveSupport @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 def #{name}(halted, value) if #{@compiled_options}(value) && !halted - #{@source} do + #{@source}(value) do yield self end else @@ -309,35 +309,13 @@ module ActiveSupport # a method is created that calls the before_foo method # on the object. def _compile_source(filter) - case filter - when Array - filter.map {|f| _compile_source(f)} - when Symbol - filter - when String - "(#{filter})" - when ::Proc - method_name = "_callback_#{@kind}_#{next_id}" - @klass.send(:define_method, method_name, &filter) - return method_name if filter.arity <= 0 - - method_name << (filter.arity == 1 ? "(self)" : "(self, ::Proc.new)") - else - method_name = _method_name_for_object_filter(kind, filter) - @klass.send(:define_method, "#{method_name}_object") { filter } - - _normalize_legacy_filter(kind, filter) - scopes = Array(chain.config[:scope]) - method_to_call = scopes.map{ |s| public_send(s) }.join("_") - - @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def #{method_name}(&blk) - #{method_name}_object.send(:#{method_to_call}, self, &blk) - end - RUBY_EVAL + l = _compile_options filter - method_name + method_name = "_callback_#{@kind}_#{next_id}" + @klass.send(:define_method, method_name) do |*args,&block| + l.call(self, *args, &block) end + method_name end def _compile_options(filter) @@ -345,9 +323,11 @@ module ActiveSupport when Array filter.map {|f| _compile_options(f)} when Symbol - lambda { |target, value| target.public_send filter } + lambda { |target, value, &blk| + target.send filter, &blk + } when String - l = eval "lambda { |value| #{filter} }" + l = eval "lambda { |value| #{filter} }", __FILE__, __LINE__ lambda { |target,value| target.instance_exec(value, &l) } when ::Proc if filter.arity <= 0 -- cgit v1.2.3 From bf6429c438bcc74e5b1248c4293bcf6bbbce228e Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 May 2013 17:57:06 -0700 Subject: fix method names --- activesupport/lib/active_support/callbacks.rb | 84 ++++++++++++++------------- 1 file changed, 44 insertions(+), 40 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index abbb5956d0..192e0b2597 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -215,6 +215,45 @@ module ActiveSupport private + def invert_lambda(l) + lambda { |*args, &blk| !l.call(*args, &blk) } + end + + def make_lambda(filter) + case filter + when Array + filter.map {|f| _compile_options(f)} + when Symbol + lambda { |target, value, &blk| + target.send filter, &blk + } + when String + l = eval "lambda { |value| #{filter} }" + lambda { |target,value| target.instance_exec(value, &l) } + when ::Proc + if filter.arity <= 0 + return lambda { |target, _| target.instance_exec(&filter) } + end + + if filter.arity == 1 + lambda { |target, _| + target.instance_exec(target, &filter) + } + else + lambda { |target, _| + target.instance_exec target, ::Proc.new, &filter + } + end + else + scopes = Array(chain.config[:scope]) + method_to_call = scopes.map{ |s| public_send(s) }.join("_") + + lambda { |target, _, &blk| + filter.public_send method_to_call, target, &blk + } + end + end + def compute_identifier(filter) case filter when String, ::Proc @@ -261,13 +300,13 @@ module ActiveSupport conditions = [] unless options[:if].empty? - conditions.concat Array(_compile_options(options[:if])) + lambdas = Array(options[:if]).map { |c| make_lambda c } + conditions.concat lambdas end unless options[:unless].empty? - conditions.concat Array(_compile_options(options[:unless])).map { |f| - lambda { |*args,&blk| !f.call(*args, &blk) } - } + lambdas = Array(options[:unless]).map { |c| make_lambda c } + conditions.concat lambdas.map { |l| invert_lambda l } end method_name = "_callback_#{@kind}_#{next_id}" @@ -309,7 +348,7 @@ module ActiveSupport # a method is created that calls the before_foo method # on the object. def _compile_source(filter) - l = _compile_options filter + l = make_lambda filter method_name = "_callback_#{@kind}_#{next_id}" @klass.send(:define_method, method_name) do |*args,&block| @@ -318,41 +357,6 @@ module ActiveSupport method_name end - def _compile_options(filter) - case filter - when Array - filter.map {|f| _compile_options(f)} - when Symbol - lambda { |target, value, &blk| - target.send filter, &blk - } - when String - l = eval "lambda { |value| #{filter} }", __FILE__, __LINE__ - lambda { |target,value| target.instance_exec(value, &l) } - when ::Proc - if filter.arity <= 0 - return lambda { |target, _| target.instance_exec(&filter) } - end - - if filter.arity == 1 - lambda { |target, _| - target.instance_exec(target, &filter) - } - else - lambda { |target, _| - target.instance_exec target, ::Proc.new, &filter - } - end - else - scopes = Array(chain.config[:scope]) - method_to_call = scopes.map{ |s| public_send(s) }.join("_") - - lambda { |target, _, &blk| - filter.public_send method_to_call, target, &blk - } - end - end - def _normalize_legacy_filter(kind, filter) if !filter.respond_to?(kind) && filter.respond_to?(:filter) message = "Filter object with #filter method is deprecated. Define method corresponding " \ -- cgit v1.2.3 From cc0fd31f9e8b62ec650766f02a0c8ec5f0b37a10 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 8 May 2013 17:58:02 -0700 Subject: remove dead code --- activesupport/lib/active_support/callbacks.rb | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 192e0b2597..3f4973a35f 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -317,16 +317,6 @@ module ActiveSupport @compiled_options = method_name end - def _method_name_for_object_filter(kind, filter, append_next_id = true) - class_name = filter.kind_of?(Class) ? filter.to_s : filter.class.to_s - class_name.gsub!(/<|>|#/, '') - class_name.gsub!(/\/|:/, "_") - - method_name = "_callback_#{kind}_#{class_name}" - method_name << "_#{next_id}" if append_next_id - method_name - end - # Filters support: # # Arrays:: Used in conditions. This is used to specify -- cgit v1.2.3 From 23122ab2d4e239d35a154d5ec28c2afefdd012de Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 May 2013 11:58:55 -0700 Subject: callbacks are wrapped with lambdas --- activesupport/lib/active_support/callbacks.rb | 182 +++++++++++--------------- 1 file changed, 76 insertions(+), 106 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 3f4973a35f..05204d34e4 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -119,8 +119,6 @@ module ActiveSupport @raw_filter, @options = filter, options @key = compute_identifier filter - @source = _compile_source(filter) - recompile_options! end def filter @@ -174,42 +172,57 @@ module ActiveSupport def recompile!(_options) deprecate_per_key_option(_options) _update_filter(self.options, _options) - - recompile_options! end # Wraps code with filter def apply(code) + conditions = conditions_lambdas + source = make_lambda @raw_filter + case @kind when :before - <<-RUBY_EVAL - if !halted && #{@compiled_options}(value) - # This double assignment is to prevent warnings in 1.9.3 as - # the `result` variable is not always used except if the - # terminator code refers to it. - result = result = #{@source}(value) - halted = (#{chain.config[:terminator]}) + halted_lambda = eval "lambda { |result| #{chain.config[:terminator]} }" + lambda { |target, halted, value, &block| + if !halted && conditions.all? { |c| c.call(target, value) } + result = source.call target, value + halted = halted_lambda.call result if halted - halted_callback_hook(#{@raw_filter.inspect.inspect}) + target.send :halted_callback_hook, @raw_filter.inspect end end - #{code} - RUBY_EVAL + code.call target, halted, value, &block + } when :after - <<-RUBY_EVAL - #{code} - if #{!chain.config[:skip_after_callbacks_if_terminated] || "!halted"} && #{@compiled_options}(value) - #{@source}(value) + if chain.config[:skip_after_callbacks_if_terminated] + lambda { |target, halted, value, &block| + target, halted, value = code.call target, halted, value, &block + if !halted && conditions.all? { |c| c.call(target, value) } + source.call target, value + end + [target, halted, value] + } + else + lambda { |target, halted, value, &block| + target, halted, value = code.call target, halted, value, &block + if conditions.all? { |c| c.call(target, value) } + source.call target, value + end + [target, halted, value] + } end - RUBY_EVAL when :around - name = define_conditional_callback - <<-RUBY_EVAL - #{name}(halted, value) do - #{code} - value - end - RUBY_EVAL + lambda { |target, halted, value, &block| + if !halted && conditions.all? { |c| c.call(target, value) } + retval = nil + source.call(target, value) { + retval = code.call(target, halted, value, &block) + retval.last + } + retval + else + code.call target, halted, value, &block + end + } end end @@ -219,6 +232,26 @@ module ActiveSupport lambda { |*args, &blk| !l.call(*args, &blk) } end + # Filters support: + # + # Arrays:: Used in conditions. This is used to specify + # multiple conditions. Used internally to + # merge conditions from skip_* filters. + # Symbols:: A method to call. + # Strings:: Some content to evaluate. + # Procs:: A proc to call with the object. + # Objects:: An object with a before_foo method on it to call. + # + # All of these objects are compiled into methods and handled + # the same after this point: + # + # Arrays:: Merged together into a single filter. + # Symbols:: Already methods. + # Strings:: class_eval'ed into methods. + # Procs:: define_method'ed into methods. + # Objects:: + # a method is created that calls the before_foo method + # on the object. def make_lambda(filter) case filter when Array @@ -263,40 +296,7 @@ module ActiveSupport end end - # Compile around filters with conditions into proxy methods - # that contain the conditions. - # - # For `set_callback :save, :around, :filter_name, if: :condition': - # - # def _conditional_callback_save_17 - # if condition - # filter_name do - # yield self - # end - # else - # yield self - # end - # end - def define_conditional_callback - name = "_conditional_callback_#{@kind}_#{next_id}" - @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def #{name}(halted, value) - if #{@compiled_options}(value) && !halted - #{@source}(value) do - yield self - end - else - yield self - end - end - RUBY_EVAL - name - end - - # Options support the same options as filters themselves (and support - # symbols, string, procs, and objects), so compile a conditional - # expression based on the options. - def recompile_options! + def conditions_lambdas conditions = [] unless options[:if].empty? @@ -308,43 +308,7 @@ module ActiveSupport lambdas = Array(options[:unless]).map { |c| make_lambda c } conditions.concat lambdas.map { |l| invert_lambda l } end - - method_name = "_callback_#{@kind}_#{next_id}" - @klass.send(:define_method, method_name) do |*args,&block| - conditions.all? { |c| c.call(self, *args, &block) } - end - - @compiled_options = method_name - end - - # Filters support: - # - # Arrays:: Used in conditions. This is used to specify - # multiple conditions. Used internally to - # merge conditions from skip_* filters. - # Symbols:: A method to call. - # Strings:: Some content to evaluate. - # Procs:: A proc to call with the object. - # Objects:: An object with a before_foo method on it to call. - # - # All of these objects are compiled into methods and handled - # the same after this point: - # - # Arrays:: Merged together into a single filter. - # Symbols:: Already methods. - # Strings:: class_eval'ed into methods. - # Procs:: define_method'ed into methods. - # Objects:: - # a method is created that calls the before_foo method - # on the object. - def _compile_source(filter) - l = make_lambda filter - - method_name = "_callback_#{@kind}_#{next_id}" - @klass.send(:define_method, method_name) do |*args,&block| - l.call(self, *args, &block) - end - method_name + conditions end def _normalize_legacy_filter(kind, filter) @@ -380,15 +344,19 @@ module ActiveSupport end def compile - method = ["value = nil", "halted = false"] - callbacks = "value = !halted && (!block_given? || yield)" + callbacks = lambda { |target,halted,value,&block| + value = !halted && (!block || block.call) + [target, halted, value] + } reverse_each do |callback| callbacks = callback.apply(callbacks) end - method << callbacks - method << "value" - method.join("\n") + lambda { |target, &block| + value = nil + halted = false + callbacks.call(target, halted, value, &block)[2] + } end def append(*callbacks) @@ -426,10 +394,12 @@ module ActiveSupport name = __callback_runner_name(kind) unless object.respond_to?(name, true) str = object.send("_#{kind}_callbacks").compile - class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def #{name}() #{str} end - protected :#{name} - RUBY_EVAL + class_eval do + define_method(name) do |&block| + str.call self, &block + end + protected name + end end name end -- cgit v1.2.3 From f5478d9263e9aa036a09199be7a5fe0644e02031 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 May 2013 11:59:39 -0700 Subject: make_lambda is never called with an Array --- activesupport/lib/active_support/callbacks.rb | 2 -- 1 file changed, 2 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 05204d34e4..d869770489 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -254,8 +254,6 @@ module ActiveSupport # on the object. def make_lambda(filter) case filter - when Array - filter.map {|f| _compile_options(f)} when Symbol lambda { |target, value, &blk| target.send filter, &blk -- cgit v1.2.3 From 6514ee9044f94a3e4dae01297103bbd354acc221 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 May 2013 12:06:47 -0700 Subject: no need for variable assignments, just pass the values in --- activesupport/lib/active_support/callbacks.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index d869770489..ca6937eeb3 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -255,9 +255,7 @@ module ActiveSupport def make_lambda(filter) case filter when Symbol - lambda { |target, value, &blk| - target.send filter, &blk - } + lambda { |target, value, &blk| target.send filter, &blk } when String l = eval "lambda { |value| #{filter} }" lambda { |target,value| target.instance_exec(value, &l) } @@ -351,9 +349,7 @@ module ActiveSupport end lambda { |target, &block| - value = nil - halted = false - callbacks.call(target, halted, value, &block)[2] + callbacks.call(target, false, nil, &block)[2] } end -- cgit v1.2.3 From a50088a4cc4c0575c7fffdf10e0fc3a773485f03 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 May 2013 13:39:17 -0700 Subject: callback sequence is no longer used --- activesupport/lib/active_support/callbacks.rb | 6 ------ 1 file changed, 6 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index ca6937eeb3..4ee8cf2457 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -89,8 +89,6 @@ module ActiveSupport end class Callback #:nodoc:# - @@_callback_sequence = 0 - class Basic < Callback end @@ -150,10 +148,6 @@ module ActiveSupport chain.name end - def next_id - @@_callback_sequence += 1 - end - def matches?(_kind, _filter) @kind == _kind && filter == _filter end -- cgit v1.2.3 From d5fdc0d4480f3558de9d260be26d4c7782ebc781 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 May 2013 14:40:01 -0700 Subject: reduce the number of lambas --- activesupport/lib/active_support/callbacks.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 4ee8cf2457..027b5becf1 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -341,10 +341,7 @@ module ActiveSupport reverse_each do |callback| callbacks = callback.apply(callbacks) end - - lambda { |target, &block| - callbacks.call(target, false, nil, &block)[2] - } + callbacks end def append(*callbacks) @@ -384,7 +381,7 @@ module ActiveSupport str = object.send("_#{kind}_callbacks").compile class_eval do define_method(name) do |&block| - str.call self, &block + str.call(self, false, nil, &block)[2] end protected name end -- cgit v1.2.3 From 2b1d7ea335afa46fa167a680492cdf5461c46064 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 May 2013 14:47:17 -0700 Subject: fix variable name --- activesupport/lib/active_support/callbacks.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 027b5becf1..328db8c890 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -169,7 +169,7 @@ module ActiveSupport end # Wraps code with filter - def apply(code) + def apply(next_callback) conditions = conditions_lambdas source = make_lambda @raw_filter @@ -184,12 +184,12 @@ module ActiveSupport target.send :halted_callback_hook, @raw_filter.inspect end end - code.call target, halted, value, &block + next_callback.call target, halted, value, &block } when :after if chain.config[:skip_after_callbacks_if_terminated] lambda { |target, halted, value, &block| - target, halted, value = code.call target, halted, value, &block + target, halted, value = next_callback.call target, halted, value, &block if !halted && conditions.all? { |c| c.call(target, value) } source.call target, value end @@ -197,7 +197,7 @@ module ActiveSupport } else lambda { |target, halted, value, &block| - target, halted, value = code.call target, halted, value, &block + target, halted, value = next_callback.call target, halted, value, &block if conditions.all? { |c| c.call(target, value) } source.call target, value end @@ -209,12 +209,12 @@ module ActiveSupport if !halted && conditions.all? { |c| c.call(target, value) } retval = nil source.call(target, value) { - retval = code.call(target, halted, value, &block) + retval = next_callback.call(target, halted, value, &block) retval.last } retval else - code.call target, halted, value, &block + next_callback.call target, halted, value, &block end } end -- cgit v1.2.3 From 9b5202692065ea3ed116a0098a0312a9236e9983 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 May 2013 14:55:15 -0700 Subject: fixing more variable names --- activesupport/lib/active_support/callbacks.rb | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 328db8c890..850e307857 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -170,15 +170,15 @@ module ActiveSupport # Wraps code with filter def apply(next_callback) - conditions = conditions_lambdas - source = make_lambda @raw_filter + user_conditions = conditions_lambdas + user_callback = make_lambda @raw_filter case @kind when :before halted_lambda = eval "lambda { |result| #{chain.config[:terminator]} }" lambda { |target, halted, value, &block| - if !halted && conditions.all? { |c| c.call(target, value) } - result = source.call target, value + if !halted && user_conditions.all? { |c| c.call(target, value) } + result = user_callback.call target, value halted = halted_lambda.call result if halted target.send :halted_callback_hook, @raw_filter.inspect @@ -190,25 +190,25 @@ module ActiveSupport if chain.config[:skip_after_callbacks_if_terminated] lambda { |target, halted, value, &block| target, halted, value = next_callback.call target, halted, value, &block - if !halted && conditions.all? { |c| c.call(target, value) } - source.call target, value + if !halted && user_conditions.all? { |c| c.call(target, value) } + user_callback.call target, value end [target, halted, value] } else lambda { |target, halted, value, &block| target, halted, value = next_callback.call target, halted, value, &block - if conditions.all? { |c| c.call(target, value) } - source.call target, value + if user_conditions.all? { |c| c.call(target, value) } + user_callback.call target, value end [target, halted, value] } end when :around lambda { |target, halted, value, &block| - if !halted && conditions.all? { |c| c.call(target, value) } + if !halted && user_conditions.all? { |c| c.call(target, value) } retval = nil - source.call(target, value) { + user_callback.call(target, value) { retval = next_callback.call(target, halted, value, &block) retval.last } -- cgit v1.2.3 From d4dcd6e41f4a7c202270e7d510434351ce333ebc Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 May 2013 15:04:51 -0700 Subject: pass the run block as a normal variable to the rest of the callbacks --- activesupport/lib/active_support/callbacks.rb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 850e307857..511162f20f 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -176,7 +176,7 @@ module ActiveSupport case @kind when :before halted_lambda = eval "lambda { |result| #{chain.config[:terminator]} }" - lambda { |target, halted, value, &block| + lambda { |target, halted, value, run_block| if !halted && user_conditions.all? { |c| c.call(target, value) } result = user_callback.call target, value halted = halted_lambda.call result @@ -184,20 +184,20 @@ module ActiveSupport target.send :halted_callback_hook, @raw_filter.inspect end end - next_callback.call target, halted, value, &block + next_callback.call target, halted, value, run_block } when :after if chain.config[:skip_after_callbacks_if_terminated] - lambda { |target, halted, value, &block| - target, halted, value = next_callback.call target, halted, value, &block + lambda { |target, halted, value, run_block| + target, halted, value = next_callback.call target, halted, value, run_block if !halted && user_conditions.all? { |c| c.call(target, value) } user_callback.call target, value end [target, halted, value] } else - lambda { |target, halted, value, &block| - target, halted, value = next_callback.call target, halted, value, &block + lambda { |target, halted, value, run_block| + target, halted, value = next_callback.call target, halted, value, run_block if user_conditions.all? { |c| c.call(target, value) } user_callback.call target, value end @@ -205,16 +205,16 @@ module ActiveSupport } end when :around - lambda { |target, halted, value, &block| + lambda { |target, halted, value, run_block| if !halted && user_conditions.all? { |c| c.call(target, value) } retval = nil user_callback.call(target, value) { - retval = next_callback.call(target, halted, value, &block) + retval = next_callback.call(target, halted, value, run_block) retval.last } retval else - next_callback.call target, halted, value, &block + next_callback.call target, halted, value, run_block end } end @@ -334,8 +334,8 @@ module ActiveSupport end def compile - callbacks = lambda { |target,halted,value,&block| - value = !halted && (!block || block.call) + callbacks = lambda { |target, halted, value, run_block| + value = run_block.call if run_block && !halted [target, halted, value] } reverse_each do |callback| @@ -381,7 +381,7 @@ module ActiveSupport str = object.send("_#{kind}_callbacks").compile class_eval do define_method(name) do |&block| - str.call(self, false, nil, &block)[2] + str.call(self, false, nil, block)[2] end protected name end -- cgit v1.2.3 From 95e7e56efcad98b6b89e407ced78512ea16268e6 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 May 2013 15:12:31 -0700 Subject: object based callbacks cannot be duplicated --- activesupport/lib/active_support/callbacks.rb | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 511162f20f..2ea41ab2f2 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -89,10 +89,7 @@ module ActiveSupport end class Callback #:nodoc:# - class Basic < Callback - end - - class Object < Callback + class Unduplicable < Callback # :nodoc: def duplicates?(other) false end @@ -100,10 +97,10 @@ module ActiveSupport def self.build(chain, filter, kind, options, _klass) klass = case filter - when Array, Symbol, String - Callback::Basic + when Symbol, String + Callback else - Callback::Object + Callback::Unduplicable end klass.new chain, filter, kind, options, _klass end -- cgit v1.2.3 From 355169012011d9ef565ed75ce8b734346fe8c00c Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 9 May 2013 15:22:27 -0700 Subject: use an environment object to hold state about the filter calls --- activesupport/lib/active_support/callbacks.rb | 62 ++++++++++++++++++--------- 1 file changed, 41 insertions(+), 21 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 2ea41ab2f2..141c246396 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -88,6 +88,10 @@ module ActiveSupport def halted_callback_hook(filter) end + module Filters + Environment = Struct.new(:target, :halted, :value, :run_block) + end + class Callback #:nodoc:# class Unduplicable < Callback # :nodoc: def duplicates?(other) @@ -173,45 +177,60 @@ module ActiveSupport case @kind when :before halted_lambda = eval "lambda { |result| #{chain.config[:terminator]} }" - lambda { |target, halted, value, run_block| + lambda { |env| + target = env.target + value = env.value + halted = env.halted + if !halted && user_conditions.all? { |c| c.call(target, value) } result = user_callback.call target, value - halted = halted_lambda.call result - if halted + env.halted = halted_lambda.call result + if env.halted target.send :halted_callback_hook, @raw_filter.inspect end end - next_callback.call target, halted, value, run_block + next_callback.call env } when :after if chain.config[:skip_after_callbacks_if_terminated] - lambda { |target, halted, value, run_block| - target, halted, value = next_callback.call target, halted, value, run_block + lambda { |env| + env = next_callback.call env + target = env.target + value = env.value + halted = env.halted + if !halted && user_conditions.all? { |c| c.call(target, value) } user_callback.call target, value end - [target, halted, value] + env } else - lambda { |target, halted, value, run_block| - target, halted, value = next_callback.call target, halted, value, run_block + lambda { |env| + env = next_callback.call env + target = env.target + value = env.value + halted = env.halted + if user_conditions.all? { |c| c.call(target, value) } user_callback.call target, value end - [target, halted, value] + env } end when :around - lambda { |target, halted, value, run_block| + lambda { |env| + target = env.target + value = env.value + halted = env.halted + if !halted && user_conditions.all? { |c| c.call(target, value) } - retval = nil user_callback.call(target, value) { - retval = next_callback.call(target, halted, value, run_block) - retval.last + env = next_callback.call env + env.value } - retval + env else - next_callback.call target, halted, value, run_block + next_callback.call env end } end @@ -331,9 +350,9 @@ module ActiveSupport end def compile - callbacks = lambda { |target, halted, value, run_block| - value = run_block.call if run_block && !halted - [target, halted, value] + callbacks = lambda { |env| + env.value = env.run_block.call if env.run_block && !env.halted + env } reverse_each do |callback| callbacks = callback.apply(callbacks) @@ -375,10 +394,11 @@ module ActiveSupport def __define_callbacks(kind, object) #:nodoc: name = __callback_runner_name(kind) unless object.respond_to?(name, true) - str = object.send("_#{kind}_callbacks").compile + filter_chain = object.send("_#{kind}_callbacks").compile class_eval do define_method(name) do |&block| - str.call(self, false, nil, block)[2] + e = Filters::Environment.new(self, false, nil, block) + filter_chain.call(e).value end protected name end -- cgit v1.2.3 From 9a43816928f07c4ed988fb47545d219eff55e28a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 10 May 2013 14:36:18 -0300 Subject: Fix syntax error on Ruby 2.0 Since Ruby 2.0 is UTF-8 by default we need to explictly say that the encoding of this file is US-ASCII --- activesupport/lib/active_support/json/encoding.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index 71dfbf3323..75655f88d3 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -1,3 +1,5 @@ +#encoding: us-ascii + require 'active_support/core_ext/object/to_json' require 'active_support/core_ext/module/delegation' require 'active_support/json/variable' @@ -123,9 +125,9 @@ module ActiveSupport def escape_html_entities_in_json=(value) self.escape_regex = \ if @escape_html_entities_in_json = value - /\xe2\x80(\xa8|\xa9)|[\x00-\x1F"\\><&]/ + /\xe2\x80\xa8|\xe2\x80\xa9|[\x00-\x1F"\\><&]/ else - /\xe2\x80(\xa8|\xa9)|[\x00-\x1F"\\]/ + /\xe2\x80\xa8|\xe2\x80\xa9|[\x00-\x1F"\\]/ end end -- cgit v1.2.3 From 5bc4740dec7ec9846915f7af459056d486b9c89d Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 10:53:46 -0700 Subject: fixing activemodel tests --- activesupport/lib/active_support/callbacks.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 141c246396..7c71524ffe 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -351,7 +351,8 @@ module ActiveSupport def compile callbacks = lambda { |env| - env.value = env.run_block.call if env.run_block && !env.halted + block = env.run_block + env.value = !env.halted && (!block || block.call) env } reverse_each do |callback| -- cgit v1.2.3 From 3aee9126aa6309538ee64064dcabcd34d7cc7d26 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 10:56:09 -0700 Subject: use delegation over inheritance so we can figure when to cache / bust cache --- activesupport/lib/active_support/callbacks.rb | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 7c71524ffe..13dccf328c 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -338,7 +338,9 @@ module ActiveSupport end # An Array with a compile method. - class CallbackChain < Array #:nodoc:# + class CallbackChain #:nodoc:# + include Enumerable + attr_reader :name, :config def initialize(name, config) @@ -347,6 +349,18 @@ module ActiveSupport :terminator => "false", :scope => [ :kind ] }.merge!(config) + @chain = [] + end + + def each(&block); @chain.each(&block); end + def index(o); @chain.index(o); end + def insert(index, o); @chain.insert(index, o); end + def delete(o); @chain.delete(o); end + def clear; @chain.clear; self; end + def empty?; @chain.empty?; end + + def initialize_copy(other) + @chain = other.chain.dup end def compile @@ -355,7 +369,7 @@ module ActiveSupport env.value = !env.halted && (!block || block.call) env } - reverse_each do |callback| + @chain.reverse_each do |callback| callbacks = callback.apply(callbacks) end callbacks @@ -369,20 +383,23 @@ module ActiveSupport callbacks.each { |c| prepend_one(c) } end + protected + def chain; @chain; end + private def append_one(callback) remove_duplicates(callback) - push(callback) + @chain.push(callback) end def prepend_one(callback) remove_duplicates(callback) - unshift(callback) + @chain.unshift(callback) end def remove_duplicates(callback) - delete_if { |c| callback.duplicates?(c) } + @chain.delete_if { |c| callback.duplicates?(c) } end end -- cgit v1.2.3 From ade7d365e434b586a4c1747d917beb986cb35fc7 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 11:00:25 -0700 Subject: cache compiled callbacks --- activesupport/lib/active_support/callbacks.rb | 34 +++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 13dccf328c..32234431a6 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -350,29 +350,46 @@ module ActiveSupport :scope => [ :kind ] }.merge!(config) @chain = [] + @callbacks = nil end def each(&block); @chain.each(&block); end def index(o); @chain.index(o); end - def insert(index, o); @chain.insert(index, o); end - def delete(o); @chain.delete(o); end - def clear; @chain.clear; self; end def empty?; @chain.empty?; end + def insert(index, o) + @callbacks = nil + @chain.insert(index, o) + end + + def delete(o) + @callbacks = nil + @chain.delete(o) + end + + def clear + @callbacks = nil + @chain.clear + self + end + def initialize_copy(other) - @chain = other.chain.dup + @callbacks = nil + @chain = other.chain.dup end def compile - callbacks = lambda { |env| + return @callbacks if @callbacks + + @callbacks = lambda { |env| block = env.run_block env.value = !env.halted && (!block || block.call) env } @chain.reverse_each do |callback| - callbacks = callback.apply(callbacks) + @callbacks = callback.apply(@callbacks) end - callbacks + @callbacks end def append(*callbacks) @@ -389,16 +406,19 @@ module ActiveSupport private def append_one(callback) + @callbacks = nil remove_duplicates(callback) @chain.push(callback) end def prepend_one(callback) + @callbacks = nil remove_duplicates(callback) @chain.unshift(callback) end def remove_duplicates(callback) + @callbacks = nil @chain.delete_if { |c| callback.duplicates?(c) } end -- cgit v1.2.3 From d1316bb128b1905995ba9f3e4ff35a628b845780 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 11:05:47 -0700 Subject: just run compiled callbacks since they are cached --- activesupport/lib/active_support/callbacks.rb | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 32234431a6..4b5c1ed538 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -76,8 +76,9 @@ module ActiveSupport # save # end def run_callbacks(kind, &block) - runner_name = self.class.__define_callbacks(kind, self) - send(runner_name, &block) + runner = self.class.__define_callbacks(kind, self) + e = Filters::Environment.new(self, false, nil, block) + runner.call(e).value end private @@ -430,18 +431,7 @@ module ActiveSupport # if it was not yet defined. # This generated method plays caching role. def __define_callbacks(kind, object) #:nodoc: - name = __callback_runner_name(kind) - unless object.respond_to?(name, true) - filter_chain = object.send("_#{kind}_callbacks").compile - class_eval do - define_method(name) do |&block| - e = Filters::Environment.new(self, false, nil, block) - filter_chain.call(e).value - end - protected name - end - end - name + object.send("_#{kind}_callbacks").compile end def __reset_runner(symbol) -- cgit v1.2.3 From a3e9d6bb22774c3f7ec22c3f8bfeabf56ed8436d Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 11:06:27 -0700 Subject: __define_callbacks method is not necessary anymore --- activesupport/lib/active_support/callbacks.rb | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 4b5c1ed538..715e4cf8a1 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -76,7 +76,7 @@ module ActiveSupport # save # end def run_callbacks(kind, &block) - runner = self.class.__define_callbacks(kind, self) + runner = send("_#{kind}_callbacks").compile e = Filters::Environment.new(self, false, nil, block) runner.call(e).value end @@ -427,13 +427,6 @@ module ActiveSupport module ClassMethods - # This method defines callback chain method for the given kind - # if it was not yet defined. - # This generated method plays caching role. - def __define_callbacks(kind, object) #:nodoc: - object.send("_#{kind}_callbacks").compile - end - def __reset_runner(symbol) name = __callback_runner_name(symbol) undef_method(name) if method_defined?(name) -- cgit v1.2.3 From c5ed42a60281c24c34a0f7b28a72835a52ea7fc7 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 11:08:25 -0700 Subject: callback chain is in charge of the cache, so remove method based cache --- activesupport/lib/active_support/callbacks.rb | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 715e4cf8a1..faa24d09de 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -427,23 +427,6 @@ module ActiveSupport module ClassMethods - def __reset_runner(symbol) - name = __callback_runner_name(symbol) - undef_method(name) if method_defined?(name) - end - - def __callback_runner_name_cache - @__callback_runner_name_cache ||= ThreadSafe::Cache.new {|cache, kind| cache[kind] = __generate_callback_runner_name(kind) } - end - - def __generate_callback_runner_name(kind) - "_run__#{self.name.hash.abs}__#{kind}__callbacks" - end - - def __callback_runner_name(kind) - __callback_runner_name_cache[kind] - end - # This is used internally to append, prepend and skip callbacks to the # CallbackChain. def __update_callbacks(name, filters = [], block = nil) #:nodoc: @@ -454,7 +437,6 @@ module ActiveSupport ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse.each do |target| chain = target.send("_#{name}_callbacks") yield target, chain.dup, type, filters, options - target.__reset_runner(name) end end @@ -539,12 +521,9 @@ module ActiveSupport chain = target.send("_#{symbol}_callbacks").dup callbacks.each { |c| chain.delete(c) } target.send("_#{symbol}_callbacks=", chain) - target.__reset_runner(symbol) end self.send("_#{symbol}_callbacks=", callbacks.dup.clear) - - __reset_runner(symbol) end # Define sets of events in the object lifecycle that support callbacks. -- cgit v1.2.3 From 17dfee0a991038ed0098309ddb4fd542f31dbf57 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 11:45:48 -0700 Subject: push duplicates? logic to the instance --- activesupport/lib/active_support/callbacks.rb | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index faa24d09de..db86a532ff 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -94,20 +94,8 @@ module ActiveSupport end class Callback #:nodoc:# - class Unduplicable < Callback # :nodoc: - def duplicates?(other) - false - end - end - def self.build(chain, filter, kind, options, _klass) - klass = case filter - when Symbol, String - Callback - else - Callback::Unduplicable - end - klass.new chain, filter, kind, options, _klass + new chain, filter, kind, options, _klass end attr_accessor :chain, :kind, :options, :klass, :raw_filter @@ -155,9 +143,12 @@ module ActiveSupport end def duplicates?(other) - return false unless self.class == other.class - - matches?(other.kind, other.filter) + case @raw_filter + when Symbol, String + matches?(other.kind, other.filter) + else + false + end end def _update_filter(filter_options, new_options) -- cgit v1.2.3 From 40bdad34a5fb39cdd20887f498d4efeeae6d83c6 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 11:50:50 -0700 Subject: rename instance variables --- activesupport/lib/active_support/callbacks.rb | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index db86a532ff..0b7e73a5af 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -98,20 +98,22 @@ module ActiveSupport new chain, filter, kind, options, _klass end - attr_accessor :chain, :kind, :options, :klass, :raw_filter + attr_accessor :chain, :kind, :options, :klass def initialize(chain, filter, kind, options, klass) - @chain, @kind, @klass = chain, kind, klass + @chain = chain + @kind = kind + @klass = klass + @filter = filter + @options = options + @key = compute_identifier filter + deprecate_per_key_option(options) normalize_options!(options) - - @raw_filter, @options = filter, options - @key = compute_identifier filter end - def filter - @key - end + def filter; @key; end + def raw_filter; @filter; end def deprecate_per_key_option(options) if options[:per_key] @@ -143,7 +145,7 @@ module ActiveSupport end def duplicates?(other) - case @raw_filter + case @filter when Symbol, String matches?(other.kind, other.filter) else @@ -164,9 +166,9 @@ module ActiveSupport # Wraps code with filter def apply(next_callback) user_conditions = conditions_lambdas - user_callback = make_lambda @raw_filter + user_callback = make_lambda @filter - case @kind + case kind when :before halted_lambda = eval "lambda { |result| #{chain.config[:terminator]} }" lambda { |env| @@ -178,7 +180,7 @@ module ActiveSupport result = user_callback.call target, value env.halted = halted_lambda.call result if env.halted - target.send :halted_callback_hook, @raw_filter.inspect + target.send :halted_callback_hook, @filter.inspect end end next_callback.call env -- cgit v1.2.3 From 2efe6ce538a89c1c143d40ae5455ff85d9e21a54 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 11:55:27 -0700 Subject: remove klass because it is not used --- activesupport/lib/active_support/callbacks.rb | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 0b7e73a5af..bdcc539749 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -94,16 +94,15 @@ module ActiveSupport end class Callback #:nodoc:# - def self.build(chain, filter, kind, options, _klass) - new chain, filter, kind, options, _klass + def self.build(chain, filter, kind, options) + new chain, filter, kind, options end - attr_accessor :chain, :kind, :options, :klass + attr_accessor :chain, :kind, :options - def initialize(chain, filter, kind, options, klass) + def initialize(chain, filter, kind, options) @chain = chain @kind = kind - @klass = klass @filter = filter @options = options @key = compute_identifier filter @@ -121,10 +120,9 @@ module ActiveSupport end end - def clone(chain, klass) + def clone(chain) obj = super() obj.chain = chain - obj.klass = klass obj.options = @options.dup obj.options[:if] = @options[:if].dup obj.options[:unless] = @options[:unless].dup @@ -473,7 +471,7 @@ module ActiveSupport __update_callbacks(name, filter_list, block) do |target, chain, type, filters, options| mapped ||= filters.map do |filter| - Callback.build(chain, filter, type, options.dup, self) + Callback.build(chain, filter, type, options.dup) end options[:prepend] ? chain.prepend(*mapped) : chain.append(*mapped) @@ -495,7 +493,7 @@ module ActiveSupport filter = chain.find {|c| c.matches?(type, filter) } if filter && options.any? - new_filter = filter.clone(chain, self) + new_filter = filter.clone(chain) chain.insert(chain.index(filter), new_filter) new_filter.recompile!(options) end -- cgit v1.2.3 From 91e002e31eb50329a5936dab3286b41571868653 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 12:00:35 -0700 Subject: dup the callback and set the chain --- activesupport/lib/active_support/callbacks.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index bdcc539749..b7c0f1d484 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -120,13 +120,12 @@ module ActiveSupport end end - def clone(chain) - obj = super() - obj.chain = chain - obj.options = @options.dup - obj.options[:if] = @options[:if].dup - obj.options[:unless] = @options[:unless].dup - obj + def initialize_copy(other) + super + @options = { + :if => other.options[:if].dup, + :unless => other.options[:unless].dup + } end def normalize_options!(options) @@ -493,7 +492,8 @@ module ActiveSupport filter = chain.find {|c| c.matches?(type, filter) } if filter && options.any? - new_filter = filter.clone(chain) + new_filter = filter.dup + new_filter.chain = chain chain.insert(chain.index(filter), new_filter) new_filter.recompile!(options) end -- cgit v1.2.3 From 929658c98d48eeba7f65ec4afb0f8cbedadaf270 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 14:12:56 -0700 Subject: push merge code to the callback itself --- activesupport/lib/active_support/callbacks.rb | 28 ++++++++++----------------- 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index b7c0f1d484..0370a27f32 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -120,12 +120,16 @@ module ActiveSupport end end - def initialize_copy(other) - super - @options = { - :if => other.options[:if].dup, - :unless => other.options[:unless].dup + def merge(chain, new_options) + _options = { + :if => @options[:if].dup, + :unless => @options[:unless].dup } + + _options[:if].concat Array(new_options.fetch(:unless, [])) + _options[:unless].concat Array(new_options.fetch(:if, [])) + + self.class.new chain, @filter, @kind, _options end def normalize_options!(options) @@ -150,16 +154,6 @@ module ActiveSupport end end - def _update_filter(filter_options, new_options) - filter_options[:if].concat(Array(new_options[:unless])) if new_options.key?(:unless) - filter_options[:unless].concat(Array(new_options[:if])) if new_options.key?(:if) - end - - def recompile!(_options) - deprecate_per_key_option(_options) - _update_filter(self.options, _options) - end - # Wraps code with filter def apply(next_callback) user_conditions = conditions_lambdas @@ -492,10 +486,8 @@ module ActiveSupport filter = chain.find {|c| c.matches?(type, filter) } if filter && options.any? - new_filter = filter.dup - new_filter.chain = chain + new_filter = filter.merge(chain, options) chain.insert(chain.index(filter), new_filter) - new_filter.recompile!(options) end chain.delete(filter) -- cgit v1.2.3 From f0a9f814a3ea7237275b2c89df8b378b08e248f8 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 14:18:57 -0700 Subject: fix deprecation test --- activesupport/lib/active_support/callbacks.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 0370a27f32..76fc7a76a6 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -126,6 +126,8 @@ module ActiveSupport :unless => @options[:unless].dup } + deprecate_per_key_option new_options + _options[:if].concat Array(new_options.fetch(:unless, [])) _options[:unless].concat Array(new_options.fetch(:if, [])) -- cgit v1.2.3 From b97ff316ec6d3fa962dc804d5aeb83aa81b2d847 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 10 May 2013 15:43:34 -0700 Subject: do not keep a reference to the chain in the callback objects --- activesupport/lib/active_support/callbacks.rb | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 76fc7a76a6..e733257b67 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -95,13 +95,15 @@ module ActiveSupport class Callback #:nodoc:# def self.build(chain, filter, kind, options) - new chain, filter, kind, options + new chain.name, filter, kind, options, chain.config end - attr_accessor :chain, :kind, :options + attr_accessor :kind, :options, :name + attr_reader :chain_config - def initialize(chain, filter, kind, options) - @chain = chain + def initialize(name, filter, kind, options, chain_config) + @chain_config = chain_config + @name = name @kind = kind @filter = filter @options = options @@ -131,7 +133,7 @@ module ActiveSupport _options[:if].concat Array(new_options.fetch(:unless, [])) _options[:unless].concat Array(new_options.fetch(:if, [])) - self.class.new chain, @filter, @kind, _options + self.class.build chain, @filter, @kind, _options end def normalize_options!(options) @@ -139,10 +141,6 @@ module ActiveSupport options[:unless] = Array(options[:unless]) end - def name - chain.name - end - def matches?(_kind, _filter) @kind == _kind && filter == _filter end @@ -163,7 +161,7 @@ module ActiveSupport case kind when :before - halted_lambda = eval "lambda { |result| #{chain.config[:terminator]} }" + halted_lambda = eval "lambda { |result| #{chain_config[:terminator]} }" lambda { |env| target = env.target value = env.value @@ -179,7 +177,7 @@ module ActiveSupport next_callback.call env } when :after - if chain.config[:skip_after_callbacks_if_terminated] + if chain_config[:skip_after_callbacks_if_terminated] lambda { |env| env = next_callback.call env target = env.target @@ -271,7 +269,7 @@ module ActiveSupport } end else - scopes = Array(chain.config[:scope]) + scopes = Array(chain_config[:scope]) method_to_call = scopes.map{ |s| public_send(s) }.join("_") lambda { |target, _, &blk| -- cgit v1.2.3 From 947cc874be3e652eb76af1808fcf2fa692f4ace6 Mon Sep 17 00:00:00 2001 From: Anton Kalyaev Date: Sat, 11 May 2013 13:17:34 +0400 Subject: added docs for InheritedOptions class [ci skip] --- activesupport/lib/active_support/ordered_options.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/ordered_options.rb b/activesupport/lib/active_support/ordered_options.rb index c9518bda79..e03bb4ca0f 100644 --- a/activesupport/lib/active_support/ordered_options.rb +++ b/activesupport/lib/active_support/ordered_options.rb @@ -40,6 +40,14 @@ module ActiveSupport end end + # +InheritableOptions+ provides a constructor to build an +OrderedOptions+ + # hash inherited from the another hash. + # + # Use this if you already have some hash and you want to create a new one based on it. + # + # h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' }) + # h.girl # => 'Mary' + # h.boy # => 'John' class InheritableOptions < OrderedOptions def initialize(parent = nil) if parent.kind_of?(OrderedOptions) -- cgit v1.2.3 From ce4456fde6f45f1abd020cbdeb520d401299e01f Mon Sep 17 00:00:00 2001 From: Erik Michaels-Ober Date: Sat, 11 May 2013 13:59:37 -0700 Subject: Replace multi_json with json --- activesupport/lib/active_support/json/decoding.rb | 25 ++++------------------- 1 file changed, 4 insertions(+), 21 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/json/decoding.rb b/activesupport/lib/active_support/json/decoding.rb index a4a32b2ad0..30833a4cb1 100644 --- a/activesupport/lib/active_support/json/decoding.rb +++ b/activesupport/lib/active_support/json/decoding.rb @@ -1,6 +1,6 @@ require 'active_support/core_ext/module/attribute_accessors' require 'active_support/core_ext/module/delegation' -require 'multi_json' +require 'json' module ActiveSupport # Look for and parse json strings that look like ISO 8601 times. @@ -13,8 +13,8 @@ module ActiveSupport # # ActiveSupport::JSON.decode("{\"team\":\"rails\",\"players\":\"36\"}") # => {"team" => "rails", "players" => "36"} - def decode(json, options ={}) - data = MultiJson.load(json, options) + def decode(json, proc = nil, options = {}) + data = ::JSON.load(json, proc, options) if ActiveSupport.parse_json_times convert_dates_from(data) else @@ -22,23 +22,6 @@ module ActiveSupport end end - def engine - MultiJson.adapter - end - alias :backend :engine - - def engine=(name) - MultiJson.use(name) - end - alias :backend= :engine= - - def with_backend(name) - old_backend, self.backend = backend, name - yield - ensure - self.backend = old_backend - end - # Returns the class of the error that will be raised when there is an # error in decoding JSON. Using this method means you won't directly # depend on the ActiveSupport's JSON implementation, in case it changes @@ -50,7 +33,7 @@ module ActiveSupport # Rails.logger.warn("Attempted to decode invalid JSON: #{some_string}") # end def parse_error - MultiJson::DecodeError + ::JSON::ParserError end private -- cgit v1.2.3 From b2de3f729496a223d64f9b55192d1b19bda4fc25 Mon Sep 17 00:00:00 2001 From: Andy Lindeman Date: Sun, 12 May 2013 22:43:48 -0400 Subject: Fixes NoMethodError: `alias_method_chain` when requiring just active_support/core_ext * Each file that uses `alias_method_chain` brings it in explicitly --- activesupport/lib/active_support/core_ext/marshal.rb | 2 ++ activesupport/lib/active_support/core_ext/range/include_range.rb | 2 ++ 2 files changed, 4 insertions(+) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/marshal.rb b/activesupport/lib/active_support/core_ext/marshal.rb index c7a8348b1d..56c79c04bd 100644 --- a/activesupport/lib/active_support/core_ext/marshal.rb +++ b/activesupport/lib/active_support/core_ext/marshal.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/module/aliasing' + module Marshal class << self def load_with_autoloading(source) diff --git a/activesupport/lib/active_support/core_ext/range/include_range.rb b/activesupport/lib/active_support/core_ext/range/include_range.rb index 3af66aaf2f..3a07401c8a 100644 --- a/activesupport/lib/active_support/core_ext/range/include_range.rb +++ b/activesupport/lib/active_support/core_ext/range/include_range.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/module/aliasing' + class Range # Extends the default Range#include? to support range comparisons. # (1..5).include?(1..5) # => true -- cgit v1.2.3 From 19b9f7ba334108bd669ec6ae3bdf11d707a7d689 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 13 May 2013 12:05:22 -0700 Subject: pass the actual filter, not a string --- activesupport/lib/active_support/callbacks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index e733257b67..4819fe71de 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -171,7 +171,7 @@ module ActiveSupport result = user_callback.call target, value env.halted = halted_lambda.call result if env.halted - target.send :halted_callback_hook, @filter.inspect + target.send :halted_callback_hook, @filter end end next_callback.call env -- cgit v1.2.3 From 069ea45c5d4b0215d4aa3ce57316cfbc8db5ba9e Mon Sep 17 00:00:00 2001 From: aditya-kapoor Date: Tue, 14 May 2013 01:09:03 +0530 Subject: Removed Class Eval and used define_method instead for the SafeBuffer --- .../active_support/core_ext/string/output_safety.rb | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb index dc033ed11b..c368e7f505 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -171,18 +171,15 @@ module ActiveSupport #:nodoc: end UNSAFE_STRING_METHODS.each do |unsafe_method| - if 'String'.respond_to?(unsafe_method) - class_eval <<-EOT, __FILE__, __LINE__ + 1 - def #{unsafe_method}(*args, &block) # def capitalize(*args, &block) - to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block) - end # end - - def #{unsafe_method}!(*args) # def capitalize!(*args) - @html_safe = false # @html_safe = false - super # super - end # end - EOT - end + if String.new.respond_to?(unsafe_method) + define_method(unsafe_method.to_sym) do |*args, &block| + to_str.send(unsafe_method, *args, &block) + end + define_method("#{unsafe_method}!".to_sym) do |*args| + @html_safe = false + super(*args) + end + end end end end -- cgit v1.2.3 From 0b9b132e3293c56fb37a612c51a883df26a2b6c7 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 13 May 2013 14:02:39 -0700 Subject: no reason to make these defaulted, we always pass values in --- activesupport/lib/active_support/callbacks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index a151aa03b5..92b57ee1ce 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -439,7 +439,7 @@ module ActiveSupport # This is used internally to append, prepend and skip callbacks to the # CallbackChain. - def __update_callbacks(name, filters = [], block = nil) #:nodoc: + def __update_callbacks(name, filters, block) #:nodoc: type = CALLBACK_FILTER_TYPES.include?(filters.first) ? filters.shift : :before options = filters.last.is_a?(Hash) ? filters.pop : {} filters.unshift(block) if block -- cgit v1.2.3 From 35c4a2ca95848bf03839ebb58a98d93189c5d3aa Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 13 May 2013 14:11:09 -0700 Subject: extract callback param munging --- activesupport/lib/active_support/callbacks.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 92b57ee1ce..cc0fe51598 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -437,12 +437,17 @@ module ActiveSupport __callback_runner_name_cache[kind] end - # This is used internally to append, prepend and skip callbacks to the - # CallbackChain. - def __update_callbacks(name, filters, block) #:nodoc: + def normalize_callback_params(name, filters, block) # :nodoc: type = CALLBACK_FILTER_TYPES.include?(filters.first) ? filters.shift : :before options = filters.last.is_a?(Hash) ? filters.pop : {} filters.unshift(block) if block + [type, filters, options] + end + + # This is used internally to append, prepend and skip callbacks to the + # CallbackChain. + def __update_callbacks(name, filters, block) #:nodoc: + type, filters, options = normalize_callback_params(name, filters, block) ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse.each do |target| chain = target.send("_#{name}_callbacks") -- cgit v1.2.3 From 72be280ffe1f548fcdbff5f85b69b47c230722a7 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 13 May 2013 14:14:50 -0700 Subject: call extracted method from callback manipulation methods --- activesupport/lib/active_support/callbacks.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index cc0fe51598..8ac49ec4b6 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -446,12 +446,10 @@ module ActiveSupport # This is used internally to append, prepend and skip callbacks to the # CallbackChain. - def __update_callbacks(name, filters, block) #:nodoc: - type, filters, options = normalize_callback_params(name, filters, block) - + def __update_callbacks(name) #:nodoc: ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse.each do |target| chain = target.send("_#{name}_callbacks") - yield target, chain.dup, type, filters, options + yield target, chain.dup target.__reset_runner(name) end end @@ -494,7 +492,9 @@ module ActiveSupport def set_callback(name, *filter_list, &block) mapped = nil - __update_callbacks(name, filter_list, block) do |target, chain, type, filters, options| + type, filters, options = normalize_callback_params(name, filter_list, block) + + __update_callbacks(name) do |target, chain| mapped ||= filters.map do |filter| Callback.build(chain, filter, type, options.dup, self) end @@ -513,7 +513,9 @@ module ActiveSupport # skip_callback :validate, :before, :check_membership, if: -> { self.age > 18 } # end def skip_callback(name, *filter_list, &block) - __update_callbacks(name, filter_list, block) do |target, chain, type, filters, options| + type, filters, options = normalize_callback_params(name, filter_list, block) + + __update_callbacks(name) do |target, chain| filters.each do |filter| filter = chain.find {|c| c.matches?(type, filter) } -- cgit v1.2.3 From b93cd60949bfc8d69b271e09eda0786b200e7a8b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 13 May 2013 14:23:03 -0700 Subject: extract getting an setting callbacks to methods --- activesupport/lib/active_support/callbacks.rb | 37 ++++++++++++++++----------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 8ac49ec4b6..fc63fb8c8e 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -448,7 +448,7 @@ module ActiveSupport # CallbackChain. def __update_callbacks(name) #:nodoc: ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse.each do |target| - chain = target.send("_#{name}_callbacks") + chain = target.get_callbacks name yield target, chain.dup target.__reset_runner(name) end @@ -490,18 +490,15 @@ module ActiveSupport # * :prepend - If +true+, the callback will be prepended to the # existing chain rather than appended. def set_callback(name, *filter_list, &block) - mapped = nil - type, filters, options = normalize_callback_params(name, filter_list, block) + chain = get_callbacks name + mapped = filters.map do |filter| + Callback.build(chain, filter, type, options.dup, self) + end __update_callbacks(name) do |target, chain| - mapped ||= filters.map do |filter| - Callback.build(chain, filter, type, options.dup, self) - end - options[:prepend] ? chain.prepend(*mapped) : chain.append(*mapped) - - target.send("_#{name}_callbacks=", chain) + target.set_callbacks name, chain end end @@ -527,22 +524,22 @@ module ActiveSupport chain.delete(filter) end - target.send("_#{name}_callbacks=", chain) + target.set_callbacks name, chain end end # Remove all set callbacks for the given event. def reset_callbacks(symbol) - callbacks = send("_#{symbol}_callbacks") + callbacks = get_callbacks symbol ActiveSupport::DescendantsTracker.descendants(self).each do |target| - chain = target.send("_#{symbol}_callbacks").dup + chain = target.get_callbacks(symbol).dup callbacks.each { |c| chain.delete(c) } - target.send("_#{symbol}_callbacks=", chain) + target.set_callbacks symbol, chain target.__reset_runner(symbol) end - self.send("_#{symbol}_callbacks=", callbacks.dup.clear) + self.set_callbacks symbol, callbacks.dup.clear __reset_runner(symbol) end @@ -618,9 +615,19 @@ module ActiveSupport config = callbacks.last.is_a?(Hash) ? callbacks.pop : {} callbacks.each do |callback| class_attribute "_#{callback}_callbacks" - send("_#{callback}_callbacks=", CallbackChain.new(callback, config)) + set_callbacks callback, CallbackChain.new(callback, config) end end + + protected + + def get_callbacks(name) + send "_#{name}_callbacks" + end + + def set_callbacks(name, callbacks) + send "_#{name}_callbacks=", callbacks + end end end end -- cgit v1.2.3 From b308f0d4f160307d03c5c7816d536042dc69941d Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 13 May 2013 15:50:16 -0700 Subject: raise an argument error if the filter arity is greater than 1 --- activesupport/lib/active_support/callbacks.rb | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 2eec360042..fc797262d9 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -250,23 +250,17 @@ module ActiveSupport def make_lambda(filter) case filter when Symbol - lambda { |target, value, &blk| target.send filter, &blk } + lambda { |target, _, &blk| target.send filter, &blk } when String l = eval "lambda { |value| #{filter} }" - lambda { |target,value| target.instance_exec(value, &l) } + lambda { |target, value| target.instance_exec(value, &l) } when ::Proc - if filter.arity <= 0 - return lambda { |target, _| target.instance_exec(&filter) } - end + raise ArgumentError if filter.arity > 1 - if filter.arity == 1 - lambda { |target, _| - target.instance_exec(target, &filter) - } + if filter.arity <= 0 + lambda { |target, _| target.instance_exec(&filter) } else - lambda { |target, _| - target.instance_exec target, ::Proc.new, &filter - } + lambda { |target, _| target.instance_exec(target, &filter) } end else scopes = Array(chain_config[:scope]) -- cgit v1.2.3 From 9caf0cf9c8c7b42737ae78c470a5dd2f583ada75 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 13 May 2013 15:54:45 -0700 Subject: we never pass blocks, so remove this --- activesupport/lib/active_support/callbacks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index fc797262d9..d175465d4d 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -250,7 +250,7 @@ module ActiveSupport def make_lambda(filter) case filter when Symbol - lambda { |target, _, &blk| target.send filter, &blk } + lambda { |target, _| target.send filter } when String l = eval "lambda { |value| #{filter} }" lambda { |target, value| target.instance_exec(value, &l) } -- cgit v1.2.3 From 877964dc61d56f7579871ad434622748f4e208f9 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 13 May 2013 16:17:29 -0700 Subject: Arrays are no longer supported --- activesupport/lib/active_support/callbacks.rb | 4 ---- 1 file changed, 4 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index d175465d4d..6ffe8a750d 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -229,9 +229,6 @@ module ActiveSupport # Filters support: # - # Arrays:: Used in conditions. This is used to specify - # multiple conditions. Used internally to - # merge conditions from skip_* filters. # Symbols:: A method to call. # Strings:: Some content to evaluate. # Procs:: A proc to call with the object. @@ -240,7 +237,6 @@ module ActiveSupport # All of these objects are compiled into methods and handled # the same after this point: # - # Arrays:: Merged together into a single filter. # Symbols:: Already methods. # Strings:: class_eval'ed into methods. # Procs:: define_method'ed into methods. -- cgit v1.2.3 From ccbefff684d63c71e13fbb7507fa41d3400c0c95 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 13 May 2013 16:43:27 -0700 Subject: if there is nothing to compile, then do not bother compiling --- activesupport/lib/active_support/callbacks.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 6ffe8a750d..8422d4f5f3 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -76,9 +76,14 @@ module ActiveSupport # save # end def run_callbacks(kind, &block) - runner = send("_#{kind}_callbacks").compile - e = Filters::Environment.new(self, false, nil, block) - runner.call(e).value + cbs = send("_#{kind}_callbacks") + if cbs.empty? + yield if block_given? + else + runner = cbs.compile + e = Filters::Environment.new(self, false, nil, block) + runner.call(e).value + end end private -- cgit v1.2.3 From d2c0571bf6161e859ccc9c91a7d87b2bffa35dd5 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 13 May 2013 16:53:08 -0700 Subject: Revert "we never pass blocks, so remove this" This reverts commit 9caf0cf9c8c7b42737ae78c470a5dd2f583ada75. --- activesupport/lib/active_support/callbacks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 8422d4f5f3..fa37b24f51 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -251,7 +251,7 @@ module ActiveSupport def make_lambda(filter) case filter when Symbol - lambda { |target, _| target.send filter } + lambda { |target, _, &blk| target.send filter, &blk } when String l = eval "lambda { |value| #{filter} }" lambda { |target, value| target.instance_exec(value, &l) } -- cgit v1.2.3 From 73aefee3f23f54786c69f1bafa5b1f0b5aee8398 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 13 May 2013 16:59:05 -0700 Subject: use a singleton end node --- activesupport/lib/active_support/callbacks.rb | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index fa37b24f51..3be23c17e1 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -96,6 +96,15 @@ module ActiveSupport module Filters Environment = Struct.new(:target, :halted, :value, :run_block) + + class End + def call(env) + block = env.run_block + env.value = !env.halted && (!block || block.call) + env + end + end + ENDING = End.new end class Callback #:nodoc:# @@ -361,11 +370,7 @@ module ActiveSupport def compile return @callbacks if @callbacks - @callbacks = lambda { |env| - block = env.run_block - env.value = !env.halted && (!block || block.call) - env - } + @callbacks = Filters::ENDING @chain.reverse_each do |callback| @callbacks = callback.apply(@callbacks) end -- cgit v1.2.3 From 426f42c09287c218466ccb060552a8717be0513f Mon Sep 17 00:00:00 2001 From: aditya-kapoor Date: Tue, 14 May 2013 19:36:35 +0530 Subject: Added a blank space and removed to_sym --- .../lib/active_support/core_ext/string/output_safety.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb index c368e7f505..7c21abea72 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -172,14 +172,15 @@ module ActiveSupport #:nodoc: UNSAFE_STRING_METHODS.each do |unsafe_method| if String.new.respond_to?(unsafe_method) - define_method(unsafe_method.to_sym) do |*args, &block| - to_str.send(unsafe_method, *args, &block) + define_method(unsafe_method) do |*args, &block| + to_str.send(unsafe_method, *args, &block) end - define_method("#{unsafe_method}!".to_sym) do |*args| + + define_method("#{unsafe_method}!") do |*args| @html_safe = false super(*args) end - end + end end end end -- cgit v1.2.3 From eac50bc3359ca3dabfe5d8fea31c6a904362dbf3 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 11:20:34 -0700 Subject: polymorphic before callbacks --- activesupport/lib/active_support/callbacks.rb | 70 +++++++++++++++++++++------ 1 file changed, 54 insertions(+), 16 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 3be23c17e1..7ea77d5857 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -105,6 +105,59 @@ module ActiveSupport end end ENDING = End.new + + class Before + def self.build(next_callback, user_callback, user_conditions, chain_config, filter) + if chain_config.key?(:terminator) && user_conditions.any? + halted_lambda = eval "lambda { |result| #{chain_config[:terminator]} }" + lambda { |env| + target = env.target + value = env.value + halted = env.halted + + if !halted && user_conditions.all? { |c| c.call(target, value) } + result = user_callback.call target, value + env.halted = halted_lambda.call result + if env.halted + target.send :halted_callback_hook, filter + end + end + next_callback.call env + } + elsif chain_config.key? :terminator + halted_lambda = eval "lambda { |result| #{chain_config[:terminator]} }" + lambda { |env| + target = env.target + value = env.value + halted = env.halted + + if !halted + result = user_callback.call target, value + env.halted = halted_lambda.call result + if env.halted + target.send :halted_callback_hook, filter + end + end + next_callback.call env + } + elsif user_conditions.any? + lambda { |env| + target = env.target + value = env.value + + if user_conditions.all? { |c| c.call(target, value) } + user_callback.call target, value + end + next_callback.call env + } + else + lambda { |env| + user_callback.call env.target, env.value + next_callback.call env + } + end + end + end end class Callback #:nodoc:# @@ -175,21 +228,7 @@ module ActiveSupport case kind when :before - halted_lambda = eval "lambda { |result| #{chain_config[:terminator]} }" - lambda { |env| - target = env.target - value = env.value - halted = env.halted - - if !halted && user_conditions.all? { |c| c.call(target, value) } - result = user_callback.call target, value - env.halted = halted_lambda.call result - if env.halted - target.send :halted_callback_hook, @filter - end - end - next_callback.call env - } + Filters::Before.build(next_callback, user_callback, user_conditions, chain_config, @filter) when :after if chain_config[:skip_after_callbacks_if_terminated] lambda { |env| @@ -335,7 +374,6 @@ module ActiveSupport def initialize(name, config) @name = name @config = { - :terminator => "false", :scope => [ :kind ] }.merge!(config) @chain = [] -- cgit v1.2.3 From bd95ff84f3199fba2c35c2727182672ac75c08b2 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 11:27:24 -0700 Subject: push the before filter lambdas to factory methods --- activesupport/lib/active_support/callbacks.rb | 98 ++++++++++++++++----------- 1 file changed, 58 insertions(+), 40 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 7ea77d5857..d0c3f4bde9 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -110,52 +110,70 @@ module ActiveSupport def self.build(next_callback, user_callback, user_conditions, chain_config, filter) if chain_config.key?(:terminator) && user_conditions.any? halted_lambda = eval "lambda { |result| #{chain_config[:terminator]} }" - lambda { |env| - target = env.target - value = env.value - halted = env.halted - - if !halted && user_conditions.all? { |c| c.call(target, value) } - result = user_callback.call target, value - env.halted = halted_lambda.call result - if env.halted - target.send :halted_callback_hook, filter - end - end - next_callback.call env - } + terminal_and_conditional(next_callback, user_callback, user_conditions, halted_lambda, filter) elsif chain_config.key? :terminator halted_lambda = eval "lambda { |result| #{chain_config[:terminator]} }" - lambda { |env| - target = env.target - value = env.value - halted = env.halted + terminal(next_callback, user_callback, halted_lambda, filter) + elsif user_conditions.any? + conditional(next_callback, user_callback, user_conditions) + else + simple next_callback, user_callback + end + end + + private + + def self.terminal_and_conditional(next_callback, user_callback, user_conditions, halted_lambda, filter) + lambda { |env| + target = env.target + value = env.value + halted = env.halted - if !halted - result = user_callback.call target, value - env.halted = halted_lambda.call result - if env.halted - target.send :halted_callback_hook, filter - end + if !halted && user_conditions.all? { |c| c.call(target, value) } + result = user_callback.call target, value + env.halted = halted_lambda.call result + if env.halted + target.send :halted_callback_hook, filter end - next_callback.call env - } - elsif user_conditions.any? - lambda { |env| - target = env.target - value = env.value + end + next_callback.call env + } + end - if user_conditions.all? { |c| c.call(target, value) } - user_callback.call target, value + def self.terminal(next_callback, user_callback, halted_lambda, filter) + lambda { |env| + target = env.target + value = env.value + halted = env.halted + + if !halted + result = user_callback.call target, value + env.halted = halted_lambda.call result + if env.halted + target.send :halted_callback_hook, filter end - next_callback.call env - } - else - lambda { |env| - user_callback.call env.target, env.value - next_callback.call env - } - end + end + next_callback.call env + } + end + + def self.conditional(next_callback, user_callback, user_conditions) + lambda { |env| + target = env.target + value = env.value + + if user_conditions.all? { |c| c.call(target, value) } + user_callback.call target, value + end + next_callback.call env + } + end + + def self.simple(next_callback, user_callback) + lambda { |env| + user_callback.call env.target, env.value + next_callback.call env + } end end end -- cgit v1.2.3 From c5953f7dba20a6706a9f3dcce4cb43d7d91aad33 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 11:30:14 -0700 Subject: rename terminal to halting, try to keep naming consistent --- activesupport/lib/active_support/callbacks.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index d0c3f4bde9..0f6610825f 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -110,10 +110,10 @@ module ActiveSupport def self.build(next_callback, user_callback, user_conditions, chain_config, filter) if chain_config.key?(:terminator) && user_conditions.any? halted_lambda = eval "lambda { |result| #{chain_config[:terminator]} }" - terminal_and_conditional(next_callback, user_callback, user_conditions, halted_lambda, filter) + halting_and_conditional(next_callback, user_callback, user_conditions, halted_lambda, filter) elsif chain_config.key? :terminator halted_lambda = eval "lambda { |result| #{chain_config[:terminator]} }" - terminal(next_callback, user_callback, halted_lambda, filter) + halting(next_callback, user_callback, halted_lambda, filter) elsif user_conditions.any? conditional(next_callback, user_callback, user_conditions) else @@ -123,7 +123,7 @@ module ActiveSupport private - def self.terminal_and_conditional(next_callback, user_callback, user_conditions, halted_lambda, filter) + def self.halting_and_conditional(next_callback, user_callback, user_conditions, halted_lambda, filter) lambda { |env| target = env.target value = env.value @@ -140,7 +140,7 @@ module ActiveSupport } end - def self.terminal(next_callback, user_callback, halted_lambda, filter) + def self.halting(next_callback, user_callback, halted_lambda, filter) lambda { |env| target = env.target value = env.value -- cgit v1.2.3 From e8ddd4f9e5b7665d7569bfebd4c8a813f8781925 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 11:37:34 -0700 Subject: polymorphic after filter --- activesupport/lib/active_support/callbacks.rb | 95 ++++++++++++++++++++------- 1 file changed, 70 insertions(+), 25 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 0f6610825f..0ae69832bd 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -176,6 +176,75 @@ module ActiveSupport } end end + + class After + def self.build(next_callback, user_callback, user_conditions, chain_config) + if chain_config[:skip_after_callbacks_if_terminated] + if chain_config.key?(:terminator) && user_conditions.any? + halting_and_conditional(next_callback, user_callback, user_conditions) + elsif chain_config.key?(:terminator) + halting(next_callback, user_callback) + elsif user_conditions.any? + conditional next_callback, user_callback, user_conditions + else + simple next_callback, user_callback + end + else + if user_conditions.any? + conditional next_callback, user_callback, user_conditions + else + simple next_callback, user_callback + end + end + end + + private + + def self.halting_and_conditional(next_callback, user_callback, user_conditions) + lambda { |env| + env = next_callback.call env + target = env.target + value = env.value + halted = env.halted + + if !halted && user_conditions.all? { |c| c.call(target, value) } + user_callback.call target, value + end + env + } + end + + def self.halting(next_callback, user_callback) + lambda { |env| + env = next_callback.call env + if !env.halted + user_callback.call env.target, env.value + end + env + } + end + + def self.conditional(next_callback, user_callback, user_conditions) + lambda { |env| + env = next_callback.call env + target = env.target + value = env.value + + if user_conditions.all? { |c| c.call(target, value) } + user_callback.call target, value + end + env + } + end + + def self.simple(next_callback, user_callback) + lambda { |env| + env = next_callback.call env + user_callback.call env.target, env.value + env + } + end + end end class Callback #:nodoc:# @@ -248,31 +317,7 @@ module ActiveSupport when :before Filters::Before.build(next_callback, user_callback, user_conditions, chain_config, @filter) when :after - if chain_config[:skip_after_callbacks_if_terminated] - lambda { |env| - env = next_callback.call env - target = env.target - value = env.value - halted = env.halted - - if !halted && user_conditions.all? { |c| c.call(target, value) } - user_callback.call target, value - end - env - } - else - lambda { |env| - env = next_callback.call env - target = env.target - value = env.value - halted = env.halted - - if user_conditions.all? { |c| c.call(target, value) } - user_callback.call target, value - end - env - } - end + Filters::After.build(next_callback, user_callback, user_conditions, chain_config) when :around lambda { |env| target = env.target -- cgit v1.2.3 From 87378b0b6d5361d380ce85e4c08b147a9e7c375b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 11:48:04 -0700 Subject: polymorphic around callbacks --- activesupport/lib/active_support/callbacks.rb | 94 ++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 15 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 0ae69832bd..cc4f589203 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -245,6 +245,84 @@ module ActiveSupport } end end + + class Around + def self.build(next_callback, user_callback, user_conditions, chain_config) + if chain_config.key?(:terminator) && user_conditions.any? + halting_and_conditional(next_callback, user_callback, user_conditions) + elsif chain_config.key? :terminator + halting(next_callback, user_callback) + elsif user_conditions.any? + conditional(next_callback, user_callback, user_conditions) + else + simple(next_callback, user_callback) + end + end + + private + + def self.halting_and_conditional(next_callback, user_callback, user_conditions) + lambda { |env| + target = env.target + value = env.value + halted = env.halted + + if !halted && user_conditions.all? { |c| c.call(target, value) } + user_callback.call(target, value) { + env = next_callback.call env + env.value + } + env + else + next_callback.call env + end + } + end + + def self.halting(next_callback, user_callback) + lambda { |env| + target = env.target + value = env.value + + if !env.halted + user_callback.call(target, value) { + env = next_callback.call env + env.value + } + env + else + next_callback.call env + end + } + end + + def self.conditional(next_callback, user_callback, user_conditions) + lambda { |env| + target = env.target + value = env.value + + if user_conditions.all? { |c| c.call(target, value) } + user_callback.call(target, value) { + env = next_callback.call env + env.value + } + env + else + next_callback.call env + end + } + end + + def self.simple(next_callback, user_callback) + lambda { |env| + user_callback.call(env.target, env.value) { + env = next_callback.call env + env.value + } + env + } + end + end end class Callback #:nodoc:# @@ -319,21 +397,7 @@ module ActiveSupport when :after Filters::After.build(next_callback, user_callback, user_conditions, chain_config) when :around - lambda { |env| - target = env.target - value = env.value - halted = env.halted - - if !halted && user_conditions.all? { |c| c.call(target, value) } - user_callback.call(target, value) { - env = next_callback.call env - env.value - } - env - else - next_callback.call env - end - } + Filters::Around.build(next_callback, user_callback, user_conditions, chain_config) end end -- cgit v1.2.3 From 78202055c971659689f6a96a5b4aa2c138cb44d2 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 12:03:33 -0700 Subject: fix shadowed variable warnings --- activesupport/lib/active_support/callbacks.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index cc4f589203..ab3bb23e88 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -507,9 +507,9 @@ module ActiveSupport @callbacks = nil end - def each(&block); @chain.each(&block); end - def index(o); @chain.index(o); end - def empty?; @chain.empty?; end + def each(&block); @chain.each(&block); end + def index(o); @chain.index(o); end + def empty?; @chain.empty?; end def insert(index, o) @callbacks = nil @@ -629,9 +629,9 @@ module ActiveSupport # existing chain rather than appended. def set_callback(name, *filter_list, &block) type, filters, options = normalize_callback_params(name, filter_list, block) - chain = get_callbacks name + self_chain = get_callbacks name mapped = filters.map do |filter| - Callback.build(chain, filter, type, options.dup) + Callback.build(self_chain, filter, type, options.dup) end __update_callbacks(name) do |target, chain| -- cgit v1.2.3 From dbee8c32588083f54857e01b20479229b2f49498 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 14:02:33 -0700 Subject: fixing arity2 test --- activesupport/lib/active_support/callbacks.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index ab3bb23e88..d2a545b6d4 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -109,10 +109,10 @@ module ActiveSupport class Before def self.build(next_callback, user_callback, user_conditions, chain_config, filter) if chain_config.key?(:terminator) && user_conditions.any? - halted_lambda = eval "lambda { |result| #{chain_config[:terminator]} }" + halted_lambda = class_eval "lambda { |result| #{chain_config[:terminator]} }", __FILE__, __LINE__ halting_and_conditional(next_callback, user_callback, user_conditions, halted_lambda, filter) elsif chain_config.key? :terminator - halted_lambda = eval "lambda { |result| #{chain_config[:terminator]} }" + halted_lambda = class_eval "lambda { |result| #{chain_config[:terminator]} }", __FILE__, __LINE__ halting(next_callback, user_callback, halted_lambda, filter) elsif user_conditions.any? conditional(next_callback, user_callback, user_conditions) @@ -431,7 +431,12 @@ module ActiveSupport l = eval "lambda { |value| #{filter} }" lambda { |target, value| target.instance_exec(value, &l) } when ::Proc - raise ArgumentError if filter.arity > 1 + if filter.arity > 1 + return lambda { |target, _, &block| + raise ArgumentError unless block + target.instance_exec(target, block, &filter) + } + end if filter.arity <= 0 lambda { |target, _| target.instance_exec(&filter) } -- cgit v1.2.3 From def815a4615817acf49fed289a87aa0debb6a4ea Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 14:08:39 -0700 Subject: halting lambda must be instance execed --- activesupport/lib/active_support/callbacks.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index d2a545b6d4..5b8a300528 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -131,7 +131,7 @@ module ActiveSupport if !halted && user_conditions.all? { |c| c.call(target, value) } result = user_callback.call target, value - env.halted = halted_lambda.call result + env.halted = target.instance_exec result, &halted_lambda if env.halted target.send :halted_callback_hook, filter end @@ -148,7 +148,7 @@ module ActiveSupport if !halted result = user_callback.call target, value - env.halted = halted_lambda.call result + env.halted = target.instance_exec result, &halted_lambda if env.halted target.send :halted_callback_hook, filter end -- cgit v1.2.3 From ba552764344bc0a3c25b8576ec11f127ceaa16da Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 16:03:09 -0700 Subject: deprecating string based terminators --- activesupport/lib/active_support/callbacks.rb | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 5b8a300528..429e4f60a4 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -108,11 +108,11 @@ module ActiveSupport class Before def self.build(next_callback, user_callback, user_conditions, chain_config, filter) + halted_lambda = chain_config[:terminator] + if chain_config.key?(:terminator) && user_conditions.any? - halted_lambda = class_eval "lambda { |result| #{chain_config[:terminator]} }", __FILE__, __LINE__ halting_and_conditional(next_callback, user_callback, user_conditions, halted_lambda, filter) elsif chain_config.key? :terminator - halted_lambda = class_eval "lambda { |result| #{chain_config[:terminator]} }", __FILE__, __LINE__ halting(next_callback, user_callback, halted_lambda, filter) elsif user_conditions.any? conditional(next_callback, user_callback, user_conditions) @@ -131,7 +131,7 @@ module ActiveSupport if !halted && user_conditions.all? { |c| c.call(target, value) } result = user_callback.call target, value - env.halted = target.instance_exec result, &halted_lambda + env.halted = halted_lambda.call(target, result) if env.halted target.send :halted_callback_hook, filter end @@ -148,7 +148,7 @@ module ActiveSupport if !halted result = user_callback.call target, value - env.halted = target.instance_exec result, &halted_lambda + env.halted = halted_lambda.call(target, result) if env.halted target.send :halted_callback_hook, filter end @@ -752,6 +752,13 @@ module ActiveSupport # would call Audit#save. def define_callbacks(*callbacks) config = callbacks.last.is_a?(Hash) ? callbacks.pop : {} + if config.key?(:terminator) && String === config[:terminator] + ActiveSupport::Deprecation.warn "String based terminators are deprecated, please use a lambda" + value = config[:terminator] + l = class_eval "lambda { |result| #{value} }", __FILE__, __LINE__ + config[:terminator] = lambda { |target, result| target.instance_exec(result, &l) } + end + callbacks.each do |callback| class_attribute "_#{callback}_callbacks" set_callbacks callback, CallbackChain.new(callback, config) -- cgit v1.2.3 From d2405a0aab6b246842163cdb1a40d2d300b7b879 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 16:15:57 -0700 Subject: use inject rather than multiple assignments --- activesupport/lib/active_support/callbacks.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 429e4f60a4..e6e2fcfb3f 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -540,11 +540,9 @@ module ActiveSupport def compile return @callbacks if @callbacks - @callbacks = Filters::ENDING - @chain.reverse_each do |callback| - @callbacks = callback.apply(@callbacks) + @callbacks = @chain.reverse.inject(Filters::ENDING) do |chain, callback| + callback.apply chain end - @callbacks end def append(*callbacks) -- cgit v1.2.3 From 132db318b324ab3829362d4aa29f1eef75ed1aea Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 16:18:11 -0700 Subject: make the compile method thread safe --- activesupport/lib/active_support/callbacks.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index e6e2fcfb3f..1386c22f45 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -1,9 +1,9 @@ -require 'thread_safe' require 'active_support/concern' require 'active_support/descendants_tracker' require 'active_support/core_ext/class/attribute' require 'active_support/core_ext/kernel/reporting' require 'active_support/core_ext/kernel/singleton_class' +require 'thread' module ActiveSupport # Callbacks are code hooks that are run at key points in an object's lifecycle. @@ -510,6 +510,7 @@ module ActiveSupport }.merge!(config) @chain = [] @callbacks = nil + @mutex = Mutex.new end def each(&block); @chain.each(&block); end @@ -535,13 +536,14 @@ module ActiveSupport def initialize_copy(other) @callbacks = nil @chain = other.chain.dup + @mutex = Mutex.new end def compile - return @callbacks if @callbacks - - @callbacks = @chain.reverse.inject(Filters::ENDING) do |chain, callback| - callback.apply chain + @callbacks || @mutex.synchronize do + @callbacks ||= @chain.reverse.inject(Filters::ENDING) do |chain, callback| + callback.apply chain + end end end -- cgit v1.2.3 From dd03f10d5258dab75da6b7ec493e6558b4ed2bac Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 14 May 2013 16:22:29 -0700 Subject: only dup the options once, the Callback object does not mutate them --- activesupport/lib/active_support/callbacks.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 1386c22f45..c4cfc11372 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -585,7 +585,7 @@ module ActiveSupport type = CALLBACK_FILTER_TYPES.include?(filters.first) ? filters.shift : :before options = filters.last.is_a?(Hash) ? filters.pop : {} filters.unshift(block) if block - [type, filters, options] + [type, filters, options.dup] end # This is used internally to append, prepend and skip callbacks to the @@ -636,7 +636,7 @@ module ActiveSupport type, filters, options = normalize_callback_params(name, filter_list, block) self_chain = get_callbacks name mapped = filters.map do |filter| - Callback.build(self_chain, filter, type, options.dup) + Callback.build(self_chain, filter, type, options) end __update_callbacks(name) do |target, chain| -- cgit v1.2.3 From f9c82f586cd73d9124d0fd89f9070e640a49adac Mon Sep 17 00:00:00 2001 From: kennyj Date: Wed, 15 May 2013 19:59:02 +0900 Subject: Fix HWIA#to_hash behavior with array of hashes. --- activesupport/lib/active_support/hash_with_indifferent_access.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb index 9a9ed02bd9..bdb8877f55 100644 --- a/activesupport/lib/active_support/hash_with_indifferent_access.rb +++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb @@ -231,7 +231,7 @@ module ActiveSupport def to_hash _new_hash= {} each do |key, value| - _new_hash[convert_key(key)] = convert_value(value,true) + _new_hash[convert_key(key)] = convert_value(value, true) end Hash.new(default).merge!(_new_hash) end @@ -246,7 +246,7 @@ module ActiveSupport _convert_for_to_hash ? value.to_hash : value.nested_under_indifferent_access elsif value.is_a?(Array) value = value.dup if value.frozen? - value.map! { |e| convert_value(e) } + value.map! { |e| convert_value(e, _convert_for_to_hash) } else value end -- cgit v1.2.3 From d433436271c5270021648a44fcf7467843d9a25f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 15 May 2013 09:18:08 -0700 Subject: use unless instead of if! --- activesupport/lib/active_support/callbacks.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index c4cfc11372..1ba6d85b95 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -146,7 +146,7 @@ module ActiveSupport value = env.value halted = env.halted - if !halted + unless halted result = user_callback.call target, value env.halted = halted_lambda.call(target, result) if env.halted @@ -217,7 +217,7 @@ module ActiveSupport def self.halting(next_callback, user_callback) lambda { |env| env = next_callback.call env - if !env.halted + unless env.halted user_callback.call env.target, env.value end env @@ -284,7 +284,7 @@ module ActiveSupport target = env.target value = env.value - if !env.halted + unless env.halted user_callback.call(target, value) { env = next_callback.call env env.value -- cgit v1.2.3 From d10cadca0cda894ce4536a3b9d9367bc6f5d9b0e Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 15 May 2013 09:28:50 -0700 Subject: simplify the condions lambda generation --- activesupport/lib/active_support/callbacks.rb | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 1ba6d85b95..6f89b16d36 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -463,18 +463,8 @@ module ActiveSupport end def conditions_lambdas - conditions = [] - - unless options[:if].empty? - lambdas = Array(options[:if]).map { |c| make_lambda c } - conditions.concat lambdas - end - - unless options[:unless].empty? - lambdas = Array(options[:unless]).map { |c| make_lambda c } - conditions.concat lambdas.map { |l| invert_lambda l } - end - conditions + Array(options[:if]).map { |c| make_lambda c } + + Array(options[:unless]).map { |c| invert_lambda make_lambda c } end def _normalize_legacy_filter(kind, filter) -- cgit v1.2.3 From 99f5add4be302a6b17f7098c1a9233a19de0fda4 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 15 May 2013 09:30:08 -0700 Subject: conditions are guaranteed to be arrays by initialize --- activesupport/lib/active_support/callbacks.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 6f89b16d36..d4c18793ca 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -463,8 +463,8 @@ module ActiveSupport end def conditions_lambdas - Array(options[:if]).map { |c| make_lambda c } + - Array(options[:unless]).map { |c| invert_lambda make_lambda c } + options[:if].map { |c| make_lambda c } + + options[:unless].map { |c| invert_lambda make_lambda c } end def _normalize_legacy_filter(kind, filter) -- cgit v1.2.3 From db78643a17af9475fde2a6730e9e9e9fc3d77ad2 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 15 May 2013 09:39:23 -0700 Subject: stop keeping a reference to the options hash --- activesupport/lib/active_support/callbacks.rb | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index d4c18793ca..1a830c03b8 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -330,7 +330,7 @@ module ActiveSupport new chain.name, filter, kind, options, chain.config end - attr_accessor :kind, :options, :name + attr_accessor :kind, :name attr_reader :chain_config def initialize(name, filter, kind, options, chain_config) @@ -338,11 +338,11 @@ module ActiveSupport @name = name @kind = kind @filter = filter - @options = options @key = compute_identifier filter + @if = Array(options[:if]) + @unless = Array(options[:unless]) deprecate_per_key_option(options) - normalize_options!(options) end def filter; @key; end @@ -356,8 +356,8 @@ module ActiveSupport def merge(chain, new_options) _options = { - :if => @options[:if].dup, - :unless => @options[:unless].dup + :if => @if.dup, + :unless => @unless.dup } deprecate_per_key_option new_options @@ -368,11 +368,6 @@ module ActiveSupport self.class.build chain, @filter, @kind, _options end - def normalize_options!(options) - options[:if] = Array(options[:if]) - options[:unless] = Array(options[:unless]) - end - def matches?(_kind, _filter) @kind == _kind && filter == _filter end @@ -463,8 +458,8 @@ module ActiveSupport end def conditions_lambdas - options[:if].map { |c| make_lambda c } + - options[:unless].map { |c| invert_lambda make_lambda c } + @if.map { |c| make_lambda c } + + @unless.map { |c| invert_lambda make_lambda c } end def _normalize_legacy_filter(kind, filter) -- cgit v1.2.3 From 1012c3e9699471248f8554d4d5bf18e7d194ac2b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 15 May 2013 09:40:58 -0700 Subject: remove deprecation notices --- activesupport/lib/active_support/callbacks.rb | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 1a830c03b8..296de94e91 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -341,27 +341,17 @@ module ActiveSupport @key = compute_identifier filter @if = Array(options[:if]) @unless = Array(options[:unless]) - - deprecate_per_key_option(options) end def filter; @key; end def raw_filter; @filter; end - def deprecate_per_key_option(options) - if options[:per_key] - raise NotImplementedError, ":per_key option is no longer supported. Use generic :if and :unless options instead." - end - end - def merge(chain, new_options) _options = { :if => @if.dup, :unless => @unless.dup } - deprecate_per_key_option new_options - _options[:if].concat Array(new_options.fetch(:unless, [])) _options[:unless].concat Array(new_options.fetch(:if, [])) -- cgit v1.2.3 From 8559871cd3c3e156aafdc3799dc6234c39ba3d62 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 15 May 2013 09:43:17 -0700 Subject: remove dead code --- activesupport/lib/active_support/callbacks.rb | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 296de94e91..bbfa74f98d 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -347,15 +347,15 @@ module ActiveSupport def raw_filter; @filter; end def merge(chain, new_options) - _options = { + options = { :if => @if.dup, :unless => @unless.dup } - _options[:if].concat Array(new_options.fetch(:unless, [])) - _options[:unless].concat Array(new_options.fetch(:if, [])) + options[:if].concat Array(new_options.fetch(:unless, [])) + options[:unless].concat Array(new_options.fetch(:if, [])) - self.class.build chain, @filter, @kind, _options + self.class.build chain, @filter, @kind, options end def matches?(_kind, _filter) @@ -451,25 +451,6 @@ module ActiveSupport @if.map { |c| make_lambda c } + @unless.map { |c| invert_lambda make_lambda c } end - - def _normalize_legacy_filter(kind, filter) - if !filter.respond_to?(kind) && filter.respond_to?(:filter) - message = "Filter object with #filter method is deprecated. Define method corresponding " \ - "to filter type (#before, #after or #around)." - ActiveSupport::Deprecation.warn message - filter.singleton_class.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def #{kind}(context, &block) filter(context, &block) end - RUBY_EVAL - elsif filter.respond_to?(:before) && filter.respond_to?(:after) && kind == :around && !filter.respond_to?(:around) - message = "Filter object with #before and #after methods is deprecated. Define #around method instead." - ActiveSupport::Deprecation.warn message - def filter.around(context) - should_continue = before(context) - yield if should_continue - after(context) - end - end - end end # An Array with a compile method. -- cgit v1.2.3 From 920753f376fca4fc8b82b7ac07d00dcb2bbeb189 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 15 May 2013 09:53:13 -0700 Subject: this variable is used, so we don't have to use double assignments --- activesupport/lib/active_support/core_ext/class/attribute.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb index 6d49b7b6e1..6fa9967a28 100644 --- a/activesupport/lib/active_support/core_ext/class/attribute.rb +++ b/activesupport/lib/active_support/core_ext/class/attribute.rb @@ -71,7 +71,7 @@ class Class def class_attribute(*attrs) options = attrs.extract_options! # 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_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) -- cgit v1.2.3 From 55975c71ec9c2c18b67020484959ff5c69d4d3fb Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 15 May 2013 09:54:14 -0700 Subject: just call the class method since we know the callbacks are stored at the class level --- activesupport/lib/active_support/callbacks.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index bbfa74f98d..37a184ed6d 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -76,7 +76,8 @@ module ActiveSupport # save # end def run_callbacks(kind, &block) - cbs = send("_#{kind}_callbacks") + cbs = self.class.send("_#{kind}_callbacks") + if cbs.empty? yield if block_given? else -- cgit v1.2.3 From ed738f75d2939a29fd901eba6d4fb0fb36f4e375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 15 May 2013 14:00:58 -0300 Subject: Revert "Merge pull request #10600 from aditya-kapoor/code_refactor" This reverts commit 8ce3c1e5dde9fb180813e4d89324db03da110b13, reversing changes made to f93da579ce7f77dbd58b9a2165861aee265b8c93. Reason: It slow down the running time. require "diffbench" load 'output_safety.rb' N = 10000 b = ActiveSupport::SafeBuffer.new("hello world") DiffBench.bm do report "capitalize in safe buffer" do N.times do b.capitalize end end end > git checkout 069ea45; diffbench bench.rb; diffbench bench.rb;diffbench bench.rb;diffbench bench.rb;diffbench bench.rb;diffbench bench.rb;diffbench bench.rb; Running benchmark with current working tree Checkout HEAD^ Running benchmark with HEAD^ Checkout to previous HEAD again user system total real ----------------------------------capitalize in safe buffer After patch: 0.010000 0.000000 0.010000 ( 0.009733) Before patch: 0.010000 0.000000 0.010000 ( 0.007702) Improvement: -26% Running benchmark with current working tree Checkout HEAD^ Running benchmark with HEAD^ Checkout to previous HEAD again user system total real ----------------------------------capitalize in safe buffer After patch: 0.010000 0.000000 0.010000 ( 0.009768) Before patch: 0.010000 0.000000 0.010000 ( 0.007896) Improvement: -24% Running benchmark with current working tree Checkout HEAD^ Running benchmark with HEAD^ Checkout to previous HEAD again user system total real ----------------------------------capitalize in safe buffer After patch: 0.010000 0.000000 0.010000 ( 0.009938) Before patch: 0.010000 0.000000 0.010000 ( 0.007768) Improvement: -28% Running benchmark with current working tree Checkout HEAD^ Running benchmark with HEAD^ Checkout to previous HEAD again user system total real ----------------------------------capitalize in safe buffer After patch: 0.010000 0.000000 0.010000 ( 0.010001) Before patch: 0.010000 0.000000 0.010000 ( 0.007873) Improvement: -27% Running benchmark with current working tree Checkout HEAD^ Running benchmark with HEAD^ Checkout to previous HEAD again user system total real ----------------------------------capitalize in safe buffer After patch: 0.010000 0.000000 0.010000 ( 0.009670) Before patch: 0.010000 0.000000 0.010000 ( 0.007800) Improvement: -24% Running benchmark with current working tree Checkout HEAD^ Running benchmark with HEAD^ Checkout to previous HEAD again user system total real ----------------------------------capitalize in safe buffer After patch: 0.010000 0.000000 0.010000 ( 0.009949) Before patch: 0.010000 0.000000 0.010000 ( 0.007752) Improvement: -28% --- .../active_support/core_ext/string/output_safety.rb | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb index 7c21abea72..dc033ed11b 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -171,15 +171,17 @@ module ActiveSupport #:nodoc: end UNSAFE_STRING_METHODS.each do |unsafe_method| - if String.new.respond_to?(unsafe_method) - define_method(unsafe_method) do |*args, &block| - to_str.send(unsafe_method, *args, &block) - end - - define_method("#{unsafe_method}!") do |*args| - @html_safe = false - super(*args) - end + if 'String'.respond_to?(unsafe_method) + class_eval <<-EOT, __FILE__, __LINE__ + 1 + def #{unsafe_method}(*args, &block) # def capitalize(*args, &block) + to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block) + end # end + + def #{unsafe_method}!(*args) # def capitalize!(*args) + @html_safe = false # @html_safe = false + super # super + end # end + EOT end end end -- cgit v1.2.3 From 2d7a86e17947e359cb65653b987c666b2d7e8efb Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Thu, 16 May 2013 11:11:27 -0700 Subject: Raise when multiple included blocks are defined --- activesupport/lib/active_support/concern.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/concern.rb b/activesupport/lib/active_support/concern.rb index eeeba60839..b6ae86b583 100644 --- a/activesupport/lib/active_support/concern.rb +++ b/activesupport/lib/active_support/concern.rb @@ -98,6 +98,12 @@ module ActiveSupport # include Bar # works, Bar takes care now of its dependencies # end module Concern + class MultipleIncludedBlocks < StandardError #:nodoc: + def initialize + super "Cannot define multiple 'included' blocks for a Concern" + end + end + def self.extended(base) #:nodoc: base.instance_variable_set("@_dependencies", []) end @@ -117,6 +123,8 @@ module ActiveSupport def included(base = nil, &block) if base.nil? + raise MultipleIncludedBlocks if instance_variable_defined?("@_included_block") + @_included_block = block else super -- cgit v1.2.3 From 156e2e3fd83ea6aa96a92149fefab37b4d6fdbf8 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 16 May 2013 14:19:36 -0700 Subject: Revert "just call the class method since we know the callbacks are stored at the" This reverts commit 55975c71ec9c2c18b67020484959ff5c69d4d3fb. --- activesupport/lib/active_support/callbacks.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 37a184ed6d..bbfa74f98d 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -76,8 +76,7 @@ module ActiveSupport # save # end def run_callbacks(kind, &block) - cbs = self.class.send("_#{kind}_callbacks") - + cbs = send("_#{kind}_callbacks") if cbs.empty? yield if block_given? else -- cgit v1.2.3