Skip to content
This repository
Browse code

Tagged the 0.9.4 release

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@444 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 1e3b5b1fcb3380603e7bb60f7dfc4e7a504e4055 1 parent e98a140
David Heinemeier Hansson authored January 17, 2005

Showing 1 changed file with 72 additions and 68 deletions. Show diff stats Hide diff stats

  1. 140  railties/lib/binding_of_caller.rb
140  railties/lib/binding_of_caller.rb
... ...
@@ -1,81 +1,85 @@
1 1
 begin
2 2
   require 'simplecc'
3 3
 rescue 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
8 10
   end
9 11
 end
10 12
 
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
  13
+class 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
42 45
 
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
56 67
         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)
58 71
       end
59  
-    elsif type == "line" then
60  
-      nil
61  
-    elsif type == "c-return" and extra_data[3] == :set_trace_func then
62  
-      nil
63  
-    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 72
     end
69  
-  end
70 73
 
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)        
  74
+    unless result
  75
+      set_trace_func(tracer)
  76
+      return nil
  77
+    else
  78
+      Thread.critical = old_critical
  79
+      case block.arity
  80
+        when 1 then yield(result)
  81
+        else yield(result, extra_data)        
  82
+      end
79 83
     end
80 84
   end
81  
-end
  85
+end

0 notes on commit 1e3b5b1

Please sign in to comment.
Something went wrong with that request. Please try again.