rescue LoadError

  class Continuation; end # :nodoc: # for RDoc
  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]
  end

end

Methods
Public Class methods
of_caller() {|result| ...}

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.

++Binding-of-Caller, Copyright © 2003 Florian Gross++

# File lib/facets/core/binding/self/of_caller.rb, line 46
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
Public Instance methods
[]( x )

Returns the value of some variable.

  a = 2
  binding["a"]  #=> 2
# File lib/facets/core/binding/op_fetch.rb, line 12
  def []( x )
    eval( x.to_s )
  end
[]=( l, v )

Set the value of a local variable.

  binding["a"] = 4
  a  #=> 4
# File lib/facets/core/binding/op_store.rb, line 12
  def []=( l, v )
    eval( "proc {|v| #{l} = v}").call( v )
  end
__DIR__()

return the directory of the file

# File lib/facets/core/binding/__LINE__.rb, line 16
  def __DIR__
    eval( "File.dirname(__FILE__)" )
  end
__FILE__()

returns file name

# File lib/facets/core/binding/__LINE__.rb, line 11
  def __FILE__
    eval( "__FILE__" )
  end
__LINE__()

returns line number

# File lib/facets/core/binding/__LINE__.rb, line 6
  def __LINE__
    eval( "__LINE__" )
  end
call_stack( level = 1 )

Returns the call stack, in array format.

# File lib/facets/core/binding/call_stack.rb, line 8
  def call_stack( level = 1 )
    eval( "call_stack( #{level} )" )
  end
called()

Retreive the current running method.

  def tester; p called; end
  tester  #=> :tester
# File lib/facets/core/binding/called.rb, line 11
  def called
    name = /\`([^\']+)\'/.match(caller(1).first)[1]
    return name.to_sym
  end
caller( skip = 0 )

Returns the call stack, same format as Kernel#caller()

# File lib/facets/core/binding/caller.rb, line 7
  def caller( skip = 0 )
    eval( "caller( #{skip} )" )
  end
defined?( x )

Returns the nature of something, nil if that thing is not defined.

# File lib/facets/core/binding/defined.rb, line 7
  def defined?( x )
    eval( "defined? #{x}" )
  end
eval( str )

Evaluate a Ruby source code string (or block) in the binding context

# File lib/facets/core/binding/eval.rb, line 5
  def eval( str ) #='', &blk )
    #if block_given?
    #  Kernel.eval( self, &blk )
    #elsif str
      Kernel.eval( str, self )
    #end
  end
local_variables()

Returns the local variables defined in the binding context

  a = 2
  binding.local_variables  #=> ["a"]
# File lib/facets/core/binding/local_variables.rb, line 11
  def local_variables()
    eval( "local_variables" )
  end
methodname()

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 methodname; end
  tester  #=> "tester"
# File lib/facets/core/binding/method_name.rb, line 13
  def methodname
    name = /\`([^\']+)\'/.match(caller(1).first)[1]
    return name
  end
self()

Returns the self in the binding context.

# File lib/facets/core/binding/self.rb, line 7
  def self()
    @self ||= eval( "self" )
    @self
  end