Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 444

Show
Ignore:
Timestamp:
01/17/05 02:30:07 (3 years ago)
Author:
david
Message:

Tagged the 0.9.4 release

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • tags/rel_0-9-4/railties/lib/binding_of_caller.rb

    r441 r444  
    22  require 'simplecc' 
    33rescue LoadError 
    4   def Continuation.create(*args, &block) #:nodoc: 
    5     cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?} 
    6     result ||= args 
    7     return *[cc, *result] 
     4  class Continuation #:nodoc: 
     5    def create(*args, &block) 
     6      cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?} 
     7      result ||= args 
     8      return *[cc, *result] 
     9    end 
    810  end 
    911end 
    1012 
    11 # This method returns the binding of the method that called your 
    12 # method. It will raise an Exception when you're not inside a method. 
    13 
    14 # It's used like this: 
    15 #   def inc_counter(amount = 1) 
    16 #     Binding.of_caller do |binding| 
    17 #       # Create a lambda that will increase the variable 'counter' 
    18 #       # in the caller of this method when called. 
    19 #       inc = eval("lambda { |arg| counter += arg }", binding) 
    20 #       # We can refer to amount from inside this block safely. 
    21 #       inc.call(amount) 
    22 #     end 
    23 #     # No other statements can go here. Put them inside the block. 
    24 #   end 
    25 #   counter = 0 
    26 #   2.times { inc_counter } 
    27 #   counter # => 2 
    28 
    29 # Binding.of_caller must be the last statement in the method. 
    30 # This means that you will have to put everything you want to 
    31 # do after the call to Binding.of_caller into the block of it. 
    32 # This should be no problem however, because Ruby has closures. 
    33 # If you don't do this an Exception will be raised. Because of 
    34 # the way that Binding.of_caller is implemented it has to be 
    35 # done this way. 
    36 def Binding.of_caller(&block) #:nodoc: 
    37   old_critical = Thread.critical 
    38   Thread.critical = true 
    39   count = 0 
    40   cc, result, error, extra_data = Continuation.create(nil, nil) 
    41   error.call if error 
     13class Binding #:nodoc: 
     14  # This method returns the binding of the method that called your 
     15  # method. It will raise an Exception when you're not inside a method. 
     16  # 
     17  # It's used like this: 
     18  #   def inc_counter(amount = 1) 
     19  #     Binding.of_caller do |binding| 
     20  #       # Create a lambda that will increase the variable 'counter' 
     21  #       # in the caller of this method when called. 
     22  #       inc = eval("lambda { |arg| counter += arg }", binding) 
     23  #       # We can refer to amount from inside this block safely. 
     24  #       inc.call(amount) 
     25  #     end 
     26  #     # No other statements can go here. Put them inside the block. 
     27  #   end 
     28  #   counter = 0 
     29  #   2.times { inc_counter } 
     30  #   counter # => 2 
     31  # 
     32  # Binding.of_caller must be the last statement in the method. 
     33  # This means that you will have to put everything you want to 
     34  # do after the call to Binding.of_caller into the block of it. 
     35  # This should be no problem however, because Ruby has closures. 
     36  # If you don't do this an Exception will be raised. Because of 
     37  # the way that Binding.of_caller is implemented it has to be 
     38  # done this way. 
     39  def of_caller(&block) 
     40    old_critical = Thread.critical 
     41    Thread.critical = true 
     42    count = 0 
     43    cc, result, error, extra_data = Continuation.create(nil, nil) 
     44    error.call if error 
    4245 
    43   tracer = lambda do |*args| 
    44     type, context, extra_data = args[0], args[4], args 
    45     if type == "return" 
    46       count += 1 
    47       # First this method and then calling one will return -- 
    48       # the trace event of the second event gets the context 
    49       # of the method which called the method that called this 
    50       # method. 
    51       if count == 2 
    52         # It would be nice if we could restore the trace_func 
    53         # that was set before we swapped in our own one, but 
    54         # this is impossible without overloading set_trace_func 
    55         # in current Ruby. 
     46    tracer = lambda do |*args| 
     47      type, context, extra_data = args[0], args[4], args 
     48      if type == "return" 
     49        count += 1 
     50        # First this method and then calling one will return -- 
     51        # the trace event of the second event gets the context 
     52        # of the method which called the method that called this 
     53        # method. 
     54        if count == 2 
     55          # It would be nice if we could restore the trace_func 
     56          # that was set before we swapped in our own one, but 
     57          # this is impossible without overloading set_trace_func 
     58          # in current Ruby. 
     59          set_trace_func(nil) 
     60          cc.call(eval("binding", context), nil, extra_data) 
     61        end 
     62      elsif type == "line" then 
     63        nil 
     64      elsif type == "c-return" and extra_data[3] == :set_trace_func then 
     65        nil 
     66      else 
    5667        set_trace_func(nil) 
    57         cc.call(eval("binding", context), nil, extra_data) 
     68        error_msg = "Binding.of_caller used in non-method context or " + 
     69          "trailing statements of method using it aren't in the block." 
     70        cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil) 
    5871      end 
    59     elsif type == "line" then 
    60       nil 
    61     elsif type == "c-return" and extra_data[3] == :set_trace_func then 
    62       nil 
     72    end 
     73 
     74    unless result 
     75      set_trace_func(tracer) 
     76      return nil 
    6377    else 
    64       set_trace_func(nil) 
    65       error_msg = "Binding.of_caller used in non-method context or " + 
    66         "trailing statements of method using it aren't in the block." 
    67       cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil) 
    68     end 
    69   end 
    70  
    71   unless result 
    72     set_trace_func(tracer) 
    73     return nil 
    74   else 
    75     Thread.critical = old_critical 
    76     case block.arity 
    77       when 1 then yield(result) 
    78       else yield(result, extra_data)         
     78      Thread.critical = old_critical 
     79      case block.arity 
     80        when 1 then yield(result) 
     81        else yield(result, extra_data)         
     82      end 
    7983    end 
    8084  end 
  • trunk/railties/lib/binding_of_caller.rb

    r441 r444  
    22  require 'simplecc' 
    33rescue LoadError 
    4   def Continuation.create(*args, &block) #:nodoc: 
    5     cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?} 
    6     result ||= args 
    7     return *[cc, *result] 
     4  class Continuation #:nodoc: 
     5    def create(*args, &block) 
     6      cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?} 
     7      result ||= args 
     8      return *[cc, *result] 
     9    end 
    810  end 
    911end 
    1012 
    11 # This method returns the binding of the method that called your 
    12 # method. It will raise an Exception when you're not inside a method. 
    13 
    14 # It's used like this: 
    15 #   def inc_counter(amount = 1) 
    16 #     Binding.of_caller do |binding| 
    17 #       # Create a lambda that will increase the variable 'counter' 
    18 #       # in the caller of this method when called. 
    19 #       inc = eval("lambda { |arg| counter += arg }", binding) 
    20 #       # We can refer to amount from inside this block safely. 
    21 #       inc.call(amount) 
    22 #     end 
    23 #     # No other statements can go here. Put them inside the block. 
    24 #   end 
    25 #   counter = 0 
    26 #   2.times { inc_counter } 
    27 #   counter # => 2 
    28 
    29 # Binding.of_caller must be the last statement in the method. 
    30 # This means that you will have to put everything you want to 
    31 # do after the call to Binding.of_caller into the block of it. 
    32 # This should be no problem however, because Ruby has closures. 
    33 # If you don't do this an Exception will be raised. Because of 
    34 # the way that Binding.of_caller is implemented it has to be 
    35 # done this way. 
    36 def Binding.of_caller(&block) #:nodoc: 
    37   old_critical = Thread.critical 
    38   Thread.critical = true 
    39   count = 0 
    40   cc, result, error, extra_data = Continuation.create(nil, nil) 
    41   error.call if error 
     13class Binding #:nodoc: 
     14  # This method returns the binding of the method that called your 
     15  # method. It will raise an Exception when you're not inside a method. 
     16  # 
     17  # It's used like this: 
     18  #   def inc_counter(amount = 1) 
     19  #     Binding.of_caller do |binding| 
     20  #       # Create a lambda that will increase the variable 'counter' 
     21  #       # in the caller of this method when called. 
     22  #       inc = eval("lambda { |arg| counter += arg }", binding) 
     23  #       # We can refer to amount from inside this block safely. 
     24  #       inc.call(amount) 
     25  #     end 
     26  #     # No other statements can go here. Put them inside the block. 
     27  #   end 
     28  #   counter = 0 
     29  #   2.times { inc_counter } 
     30  #   counter # => 2 
     31  # 
     32  # Binding.of_caller must be the last statement in the method. 
     33  # This means that you will have to put everything you want to 
     34  # do after the call to Binding.of_caller into the block of it. 
     35  # This should be no problem however, because Ruby has closures. 
     36  # If you don't do this an Exception will be raised. Because of 
     37  # the way that Binding.of_caller is implemented it has to be 
     38  # done this way. 
     39  def of_caller(&block) 
     40    old_critical = Thread.critical 
     41    Thread.critical = true 
     42    count = 0 
     43    cc, result, error, extra_data = Continuation.create(nil, nil) 
     44    error.call if error 
    4245 
    43   tracer = lambda do |*args| 
    44     type, context, extra_data = args[0], args[4], args 
    45     if type == "return" 
    46       count += 1 
    47       # First this method and then calling one will return -- 
    48       # the trace event of the second event gets the context 
    49       # of the method which called the method that called this 
    50       # method. 
    51       if count == 2 
    52         # It would be nice if we could restore the trace_func 
    53         # that was set before we swapped in our own one, but 
    54         # this is impossible without overloading set_trace_func 
    55         # in current Ruby. 
     46    tracer = lambda do |*args| 
     47      type, context, extra_data = args[0], args[4], args 
     48      if type == "return" 
     49        count += 1 
     50        # First this method and then calling one will return -- 
     51        # the trace event of the second event gets the context 
     52        # of the method which called the method that called this 
     53        # method. 
     54        if count == 2 
     55          # It would be nice if we could restore the trace_func 
     56          # that was set before we swapped in our own one, but 
     57          # this is impossible without overloading set_trace_func 
     58          # in current Ruby. 
     59          set_trace_func(nil) 
     60          cc.call(eval("binding", context), nil, extra_data) 
     61        end 
     62      elsif type == "line" then 
     63        nil 
     64      elsif type == "c-return" and extra_data[3] == :set_trace_func then 
     65        nil 
     66      else 
    5667        set_trace_func(nil) 
    57         cc.call(eval("binding", context), nil, extra_data) 
     68        error_msg = "Binding.of_caller used in non-method context or " + 
     69          "trailing statements of method using it aren't in the block." 
     70        cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil) 
    5871      end 
    59     elsif type == "line" then 
    60       nil 
    61     elsif type == "c-return" and extra_data[3] == :set_trace_func then 
    62       nil 
     72    end 
     73 
     74    unless result 
     75      set_trace_func(tracer) 
     76      return nil 
    6377    else 
    64       set_trace_func(nil) 
    65       error_msg = "Binding.of_caller used in non-method context or " + 
    66         "trailing statements of method using it aren't in the block." 
    67       cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil) 
    68     end 
    69   end 
    70  
    71   unless result 
    72     set_trace_func(tracer) 
    73     return nil 
    74   else 
    75     Thread.critical = old_critical 
    76     case block.arity 
    77       when 1 then yield(result) 
    78       else yield(result, extra_data)         
     78      Thread.critical = old_critical 
     79      case block.arity 
     80        when 1 then yield(result) 
     81        else yield(result, extra_data)         
     82      end 
    7983    end 
    8084  end