aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activesupport/lib/binding_of_caller.rb140
1 files changed, 72 insertions, 68 deletions
diff --git a/activesupport/lib/binding_of_caller.rb b/activesupport/lib/binding_of_caller.rb
index 7d31672a91..f58e87796c 100644
--- a/activesupport/lib/binding_of_caller.rb
+++ b/activesupport/lib/binding_of_caller.rb
@@ -1,81 +1,85 @@
begin
require 'simplecc'
rescue LoadError
- def Continuation.create(*args, &block) #:nodoc:
- cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
- result ||= args
- return *[cc, *result]
+ class Continuation #:nodoc:
+ def create(*args, &block)
+ cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
+ result ||= args
+ return *[cc, *result]
+ end
end
end
-# This method returns the binding of the method that called your
-# method. It will raise an Exception when you're not inside a method.
-#
-# It's used like this:
-# def inc_counter(amount = 1)
-# Binding.of_caller do |binding|
-# # Create a lambda that will increase the variable 'counter'
-# # in the caller of this method when called.
-# inc = eval("lambda { |arg| counter += arg }", binding)
-# # We can refer to amount from inside this block safely.
-# inc.call(amount)
-# end
-# # No other statements can go here. Put them inside the block.
-# end
-# counter = 0
-# 2.times { inc_counter }
-# counter # => 2
-#
-# Binding.of_caller must be the last statement in the method.
-# This means that you will have to put everything you want to
-# do after the call to Binding.of_caller into the block of it.
-# This should be no problem however, because Ruby has closures.
-# If you don't do this an Exception will be raised. Because of
-# the way that Binding.of_caller is implemented it has to be
-# done this way.
-def Binding.of_caller(&block) #:nodoc:
- old_critical = Thread.critical
- Thread.critical = true
- count = 0
- cc, result, error, extra_data = Continuation.create(nil, nil)
- error.call if error
+class Binding #:nodoc:
+ # This method returns the binding of the method that called your
+ # method. It will raise an Exception when you're not inside a method.
+ #
+ # It's used like this:
+ # def inc_counter(amount = 1)
+ # Binding.of_caller do |binding|
+ # # Create a lambda that will increase the variable 'counter'
+ # # in the caller of this method when called.
+ # inc = eval("lambda { |arg| counter += arg }", binding)
+ # # We can refer to amount from inside this block safely.
+ # inc.call(amount)
+ # end
+ # # No other statements can go here. Put them inside the block.
+ # end
+ # counter = 0
+ # 2.times { inc_counter }
+ # counter # => 2
+ #
+ # Binding.of_caller must be the last statement in the method.
+ # This means that you will have to put everything you want to
+ # do after the call to Binding.of_caller into the block of it.
+ # This should be no problem however, because Ruby has closures.
+ # If you don't do this an Exception will be raised. Because of
+ # the way that Binding.of_caller is implemented it has to be
+ # done this way.
+ def of_caller(&block)
+ old_critical = Thread.critical
+ Thread.critical = true
+ count = 0
+ cc, result, error, extra_data = Continuation.create(nil, nil)
+ error.call if error
- tracer = lambda do |*args|
- type, context, extra_data = args[0], args[4], args
- if type == "return"
- count += 1
- # First this method and then calling one will return --
- # the trace event of the second event gets the context
- # of the method which called the method that called this
- # method.
- if count == 2
- # It would be nice if we could restore the trace_func
- # that was set before we swapped in our own one, but
- # this is impossible without overloading set_trace_func
- # in current Ruby.
+ tracer = lambda do |*args|
+ type, context, extra_data = args[0], args[4], args
+ if type == "return"
+ count += 1
+ # First this method and then calling one will return --
+ # the trace event of the second event gets the context
+ # of the method which called the method that called this
+ # method.
+ if count == 2
+ # It would be nice if we could restore the trace_func
+ # that was set before we swapped in our own one, but
+ # this is impossible without overloading set_trace_func
+ # in current Ruby.
+ set_trace_func(nil)
+ cc.call(eval("binding", context), nil, extra_data)
+ end
+ elsif type == "line" then
+ nil
+ elsif type == "c-return" and extra_data[3] == :set_trace_func then
+ nil
+ else
set_trace_func(nil)
- cc.call(eval("binding", context), nil, extra_data)
+ error_msg = "Binding.of_caller used in non-method context or " +
+ "trailing statements of method using it aren't in the block."
+ cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
end
- elsif type == "line" then
- nil
- elsif type == "c-return" and extra_data[3] == :set_trace_func then
- nil
- else
- set_trace_func(nil)
- error_msg = "Binding.of_caller used in non-method context or " +
- "trailing statements of method using it aren't in the block."
- cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
end
- end
- unless result
- set_trace_func(tracer)
- return nil
- else
- Thread.critical = old_critical
- case block.arity
- when 1 then yield(result)
- else yield(result, extra_data)
+ unless result
+ set_trace_func(tracer)
+ return nil
+ else
+ Thread.critical = old_critical
+ case block.arity
+ when 1 then yield(result)
+ else yield(result, extra_data)
+ end
end
end
-end
+end \ No newline at end of file