Skip to content

Commit

Permalink
Made more stuff quiet
Browse files Browse the repository at this point in the history
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@443 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information
dhh committed Jan 17, 2005
1 parent c1a1b0b commit e98a140
Showing 1 changed file with 72 additions and 68 deletions.
140 changes: 72 additions & 68 deletions activesupport/lib/binding_of_caller.rb
@@ -1,81 +1,85 @@
begin begin
require 'simplecc' require 'simplecc'
rescue LoadError rescue LoadError
def Continuation.create(*args, &block) #:nodoc: class Continuation #:nodoc:
cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?} def create(*args, &block)
result ||= args cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
return *[cc, *result] result ||= args
return *[cc, *result]
end
end end
end end


# This method returns the binding of the method that called your class Binding #:nodoc:
# method. It will raise an Exception when you're not inside a method. # 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) # It's used like this:
# Binding.of_caller do |binding| # def inc_counter(amount = 1)
# # Create a lambda that will increase the variable 'counter' # Binding.of_caller do |binding|
# # in the caller of this method when called. # # Create a lambda that will increase the variable 'counter'
# inc = eval("lambda { |arg| counter += arg }", binding) # # in the caller of this method when called.
# # We can refer to amount from inside this block safely. # inc = eval("lambda { |arg| counter += arg }", binding)
# inc.call(amount) # # We can refer to amount from inside this block safely.
# end # inc.call(amount)
# # No other statements can go here. Put them inside the block. # end
# end # # No other statements can go here. Put them inside the block.
# counter = 0 # end
# 2.times { inc_counter } # counter = 0
# counter # => 2 # 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 # Binding.of_caller must be the last statement in the method.
# do after the call to Binding.of_caller into the block of it. # This means that you will have to put everything you want to
# This should be no problem however, because Ruby has closures. # do after the call to Binding.of_caller into the block of it.
# If you don't do this an Exception will be raised. Because of # This should be no problem however, because Ruby has closures.
# the way that Binding.of_caller is implemented it has to be # If you don't do this an Exception will be raised. Because of
# done this way. # the way that Binding.of_caller is implemented it has to be
def Binding.of_caller(&block) #:nodoc: # done this way.
old_critical = Thread.critical def of_caller(&block)
Thread.critical = true old_critical = Thread.critical
count = 0 Thread.critical = true
cc, result, error, extra_data = Continuation.create(nil, nil) count = 0
error.call if error cc, result, error, extra_data = Continuation.create(nil, nil)
error.call if error


tracer = lambda do |*args| tracer = lambda do |*args|
type, context, extra_data = args[0], args[4], args type, context, extra_data = args[0], args[4], args
if type == "return" if type == "return"
count += 1 count += 1
# First this method and then calling one will return -- # First this method and then calling one will return --
# the trace event of the second event gets the context # the trace event of the second event gets the context
# of the method which called the method that called this # of the method which called the method that called this
# method. # method.
if count == 2 if count == 2
# It would be nice if we could restore the trace_func # It would be nice if we could restore the trace_func
# that was set before we swapped in our own one, but # that was set before we swapped in our own one, but
# this is impossible without overloading set_trace_func # this is impossible without overloading set_trace_func
# in current Ruby. # 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) 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 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
end


unless result unless result
set_trace_func(tracer) set_trace_func(tracer)
return nil return nil
else else
Thread.critical = old_critical Thread.critical = old_critical
case block.arity case block.arity
when 1 then yield(result) when 1 then yield(result)
else yield(result, extra_data) else yield(result, extra_data)
end
end end
end end
end end

0 comments on commit e98a140

Please sign in to comment.