From bf6e29e00759547d5d0e0bab20434a12a449eb48 Mon Sep 17 00:00:00 2001 From: Bogdan Gusiev Date: Thu, 10 Nov 2011 10:25:27 +0200 Subject: AS::Callbacks#_define_runner refactored Incapsulate the logic of keyed callback method definition and execution in the separated method. --- activesupport/lib/active_support/callbacks.rb | 45 +++++++++++++-------------- 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'activesupport/lib/active_support/callbacks.rb') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 656cba625c..73caede7d6 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -371,42 +371,41 @@ module ActiveSupport # Generate the internal runner method called by +run_callbacks+. def __define_runner(symbol) #:nodoc: body = send("_#{symbol}_callbacks").compile + runner_method = "_run_#{symbol}_callbacks" silence_warnings do - undef_method "_run_#{symbol}_callbacks" if method_defined?("_run_#{symbol}_callbacks") + undef_method runner_method if method_defined?(runner_method) class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def _run_#{symbol}_callbacks(key = nil, &blk) + def #{runner_method}(key = nil, &blk) if key - name = "_run__\#{self.class.name.hash.abs}__#{symbol}__\#{key.hash.abs}__callbacks" - - unless respond_to?(name) - self.class.__create_keyed_callback(name, :#{symbol}, self, &blk) - end - - send(name, &blk) + self.class.__run_keyed_callback(key, :#{symbol}, self, &blk) else #{body} end end - private :_run_#{symbol}_callbacks + private :#{runner_method} RUBY_EVAL end end - # This is called the first time a callback is called with a particular - # key. It creates a new callback method for the key, calculating - # which callbacks can be omitted because of per_key conditions. - # - def __create_keyed_callback(name, kind, object, &blk) #:nodoc: - @_keyed_callbacks ||= {} - @_keyed_callbacks[name] ||= begin - str = send("_#{kind}_callbacks").compile(name, object) - class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def #{name}() #{str} end - protected :#{name} - RUBY_EVAL - true + # This method calls the callback method for the given key. + # If this called first time it creates a new callback method for the key, + # calculating which callbacks can be omitted because of per_key conditions. + # + def __run_keyed_callback(key, kind, object, &blk) #:nodoc: + name = "_run__#{self.class.name.hash.abs}__#{kind}__#{key.hash.abs}__callbacks" + unless respond_to?(name) + @_keyed_callbacks ||= {} + @_keyed_callbacks[name] ||= begin + str = send("_#{kind}_callbacks").compile(name, object) + class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def #{name}() #{str} end + protected :#{name} + RUBY_EVAL + true + end end + object.send(name, &blk) end # This is used internally to append, prepend and skip callbacks to the -- cgit v1.2.3 From 80f96ebcf5218cafd2b29e58c7b0c55a07e2fe22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 10 Nov 2011 08:57:09 -0200 Subject: self.class.name -> self.name (we are already inside a class). --- activesupport/lib/active_support/callbacks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib/active_support/callbacks.rb') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 73caede7d6..31737d54cb 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -393,7 +393,7 @@ module ActiveSupport # calculating which callbacks can be omitted because of per_key conditions. # def __run_keyed_callback(key, kind, object, &blk) #:nodoc: - name = "_run__#{self.class.name.hash.abs}__#{kind}__#{key.hash.abs}__callbacks" + name = "_run__#{self.name.hash.abs}__#{kind}__#{key.hash.abs}__callbacks" unless respond_to?(name) @_keyed_callbacks ||= {} @_keyed_callbacks[name] ||= begin -- cgit v1.2.3 From 08cc49b919cfa43a19f55b761dba56bc3673b6b7 Mon Sep 17 00:00:00 2001 From: Bogdan Gusiev Date: Thu, 10 Nov 2011 16:42:27 +0200 Subject: AS::Callbacks.__run_keyed_callback: remove unused cache --- activesupport/lib/active_support/callbacks.rb | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'activesupport/lib/active_support/callbacks.rb') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 31737d54cb..962299bf7c 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -394,16 +394,12 @@ module ActiveSupport # def __run_keyed_callback(key, kind, object, &blk) #:nodoc: name = "_run__#{self.name.hash.abs}__#{kind}__#{key.hash.abs}__callbacks" - unless respond_to?(name) - @_keyed_callbacks ||= {} - @_keyed_callbacks[name] ||= begin - str = send("_#{kind}_callbacks").compile(name, object) - class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def #{name}() #{str} end - protected :#{name} - RUBY_EVAL - true - end + unless object.respond_to?(name) + str = send("_#{kind}_callbacks").compile(name, object) + class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def #{name}() #{str} end + protected :#{name} + RUBY_EVAL end object.send(name, &blk) end -- cgit v1.2.3 From 8483c7c0a612592316dcf6048cc45e8aee101e47 Mon Sep 17 00:00:00 2001 From: Bogdan Gusiev Date: Fri, 11 Nov 2011 14:27:40 +0200 Subject: AS::Callbacks::Callback#_compile_option refactored --- activesupport/lib/active_support/callbacks.rb | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'activesupport/lib/active_support/callbacks.rb') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 962299bf7c..ea37355fc1 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -153,7 +153,7 @@ module ActiveSupport @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 def _one_time_conditions_valid_#{@callback_id}? - true #{key_options[0]} + true if #{key_options} end RUBY_EVAL end @@ -171,8 +171,8 @@ module ActiveSupport # if condition # before_save :filter_name, :if => :condition # filter_name # end - filter = <<-RUBY_EVAL - unless halted + <<-RUBY_EVAL + if !halted && #{@compiled_options} # This double assignment is to prevent warnings in 1.9.3. I would # remove the `result` variable, but apparently some other # generated code is depending on this variable being set sometimes @@ -181,8 +181,6 @@ module ActiveSupport halted = (#{chain.config[:terminator]}) end RUBY_EVAL - - [@compiled_options[0], filter, @compiled_options[1]].compact.join("\n") when :around # Compile around filters with conditions into proxy methods # that contain the conditions. @@ -202,7 +200,7 @@ module ActiveSupport name = "_conditional_callback_#{@kind}_#{next_id}" @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 def #{name}(halted) - #{@compiled_options[0] || "if true"} && !halted + if #{@compiled_options} && !halted #{@filter} do yield self end @@ -222,10 +220,12 @@ module ActiveSupport case @kind when :after - # if condition # after_save :filter_name, :if => :condition - # filter_name - # end - [@compiled_options[0], @filter, @compiled_options[1]].compact.join("\n") + # after_save :filter_name, :if => :condition + <<-RUBY_EVAL + if #{@compiled_options} + #{@filter} + end + RUBY_EVAL when :around <<-RUBY_EVAL value @@ -240,9 +240,7 @@ module ActiveSupport # symbols, string, procs, and objects), so compile a conditional # expression based on the options def _compile_options(options) - return [] if options[:if].empty? && options[:unless].empty? - - conditions = [] + conditions = ["true"] unless options[:if].empty? conditions << Array.wrap(_compile_filter(options[:if])) @@ -252,7 +250,7 @@ module ActiveSupport conditions << Array.wrap(_compile_filter(options[:unless])).map {|f| "!#{f}"} end - ["if #{conditions.flatten.join(" && ")}", "end"] + conditions.flatten.join(" && ") end # Filters support: -- cgit v1.2.3 From 38ab982cfff98570b5f12933cff489364845789c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 30 Nov 2011 09:52:52 +0100 Subject: Log 'Filter chain halted as CALLBACKNAME rendered or redirected' every time a before callback halts. --- activesupport/lib/active_support/callbacks.rb | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'activesupport/lib/active_support/callbacks.rb') diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index ea37355fc1..11069301f1 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -81,6 +81,14 @@ module ActiveSupport send("_run_#{kind}_callbacks", *args, &block) end + private + + # A hook invoked everytime a before callback is halted. + # This can be overriden in AS::Callback implementors in order + # to provide better debugging/logging. + def halted_callback_hook(filter) + end + class Callback #:nodoc:# @@_callback_sequence = 0 @@ -173,12 +181,14 @@ module ActiveSupport # end <<-RUBY_EVAL if !halted && #{@compiled_options} - # This double assignment is to prevent warnings in 1.9.3. I would - # remove the `result` variable, but apparently some other - # generated code is depending on this variable being set sometimes - # and sometimes not. + # 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} halted = (#{chain.config[:terminator]}) + if halted + halted_callback_hook(#{@raw_filter.inspect.inspect}) + end end RUBY_EVAL when :around -- cgit v1.2.3