Class: Binding
- Defined in:
- lib/nano/binding/of_caller.rb,
lib/nano/binding/eval.rb,
lib/nano/binding/self.rb,
lib/nano/binding/%5B%5D.rb,
lib/nano/binding/called.rb,
lib/nano/binding/caller.rb,
lib/nano/binding/__DIR__.rb,
lib/nano/binding/__FILE__.rb,
lib/nano/binding/__LINE__.rb,
lib/nano/binding/%5B%5D%3D.rb,
lib/nano/binding/call_stack.rb,
lib/nano/binding/defined%3F.rb,
lib/nano/binding/method_name.rb,
lib/nano/binding/%3A%3Aof_caller.rb,
lib/nano/binding/local_variables.rb
Overview
end
Class Method Summary collapse
-
.of_caller(&block) ⇒ Object
This method returns the binding of the method that called your method.
Instance Method Summary collapse
-
#[](x) ⇒ Object
Returns the value of some variable.
-
#[]=(l, v) ⇒ Object
Set the value of a local variable.
-
#__DIR__ ⇒ Object
returns line number.
-
#__FILE__ ⇒ Object
returns file name.
-
#__LINE__ ⇒ Object
returns line number.
-
#call_stack(level = 1) ⇒ Object
Returns the call stack, in array format.
-
#called ⇒ Object
Retreive the current running method.
-
#caller(skip = 0) ⇒ Object
Returns the call stack, same format as Kernel#caller().
-
#defined?(x) ⇒ Boolean
Returns the nature of something, nil if that thing is not defined.
-
#eval(str) ⇒ Object
Evaluate a Ruby source code string (or block) in the binding context.
-
#local_variables ⇒ Object
Returns the local variables defined in the binding context.
-
#method_name ⇒ Object
There is a lot of debate on what to call this.
-
#self ⇒ Object
Returns the self in the binding context.
Class Method Details
.of_caller(&block) ⇒ Object
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.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/nano/binding/of_caller.rb', line 44 def Binding.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. 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) 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) end end end |
Instance Method Details
#[](x) ⇒ Object
Returns the value of some variable.
a = 2
binding["a"] #=> 2
8 9 10 |
# File 'lib/nano/binding/%5B%5D.rb', line 8 def []( x ) eval( x.to_s ) end |
#[]=(l, v) ⇒ Object
Set the value of a local variable.
binding["a"] = 4
a #=> 4
8 9 10 |
# File 'lib/nano/binding/%5B%5D%3D.rb', line 8 def []=( l, v ) eval( "proc {|v| #{l} = v}").call( v ) end |
#__DIR__ ⇒ Object
returns line number
4 5 6 |
# File 'lib/nano/binding/__DIR__.rb', line 4 def __DIR__ eval( "File.dirname(__FILE__)" ) end |
#__FILE__ ⇒ Object
returns file name
4 5 6 |
# File 'lib/nano/binding/__FILE__.rb', line 4 def __FILE__ eval( "__FILE__" ) end |
#__LINE__ ⇒ Object
returns line number
4 5 6 |
# File 'lib/nano/binding/__LINE__.rb', line 4 def __LINE__ eval( "__LINE__" ) end |
#call_stack(level = 1) ⇒ Object
Returns the call stack, in array format.
5 6 7 |
# File 'lib/nano/binding/call_stack.rb', line 5 def call_stack( level = 1 ) eval( "call_stack( #{level} )" ) end |
#called ⇒ Object
Retreive the current running method.
def tester; p called; end
tester #=> :tester
8 9 10 11 |
# File 'lib/nano/binding/called.rb', line 8 def called name = /\`([^\']+)\'/.match(caller(1).first)[1] return name.to_sym end |
#caller(skip = 0) ⇒ Object
Returns the call stack, same format as Kernel#caller()
4 5 6 |
# File 'lib/nano/binding/caller.rb', line 4 def caller( skip = 0 ) eval( "caller( #{skip} )" ) end |
#defined?(x) ⇒ Boolean
Returns the nature of something, nil if that thing is not defined.
4 5 6 |
# File 'lib/nano/binding/defined%3F.rb', line 4 def defined?( x ) eval( "defined? #{x}" ) end |
#eval(str) ⇒ Object
Evaluate a Ruby source code string (or block) in the binding context
3 4 5 6 7 8 9 |
# File 'lib/nano/binding/eval.rb', line 3 def eval( str ) #='', &blk ) #if block_given? # Kernel.eval( self, &blk ) #elsif str Kernel.eval( str, self ) #end end |
#local_variables ⇒ Object
Returns the local variables defined in the binding context
a = 2
binding.local_variables #=> ["a"]
8 9 10 |
# File 'lib/nano/binding/local_variables.rb', line 8 def local_variables() eval( "local_variables" ) end |
#method_name ⇒ Object
There is a lot of debate on what to call this. method_name
differs from #called only by the fact that it returns a string, rather then a symbol.
def tester; p method_name; end
tester #=> "tester"
10 11 12 13 |
# File 'lib/nano/binding/method_name.rb', line 10 def method_name name = /\`([^\']+)\'/.match(caller(1).first)[1] return name end |
#self ⇒ Object
Returns the self in the binding context.
7 8 9 10 |
# File 'lib/nano/binding/self.rb', line 7 def self() @self ||= eval( "self" ) @self end |