ruby picture

RCR 251: Add Binding#eval

Submitted by batkins (Mon May 10 19:05:03 UTC 2004)

Abstract

Allows Ruby programmers to eval code within a Binding object in a more object-oriented, Rubyesque fashion.

Problem

In order to evaluate a bit of code within Binding b, you call Kernel#eval, like so:

eval "myvar = 34", b

This sets myvar to 32 within b. This isn't very object-oriented.

Proposal

Create a Binding#eval method and deprecate and/or remove the binding argument from Kernel#eval. This will allow the above code to be written as:

b.eval "myvar = 34"

Analysis

Makes eval'ing within a Binding more fitting with the Ruby Way.

Implementation

class Binding
    def eval str
        Kernel.eval str, self
    end
end

There should also be a block version.

ruby picture
Comments Current voting

I would really like to see the block version, that's what I ever missed in eval.

But that's probably not easy with the interpreter, because of two bindings inclolved, the argument and the one from the block.

Also on my wishlist would be Kernel.caller to return bindings.

Useful for debugging, I think and would allow some hacking with dynamic scoping of variables (method_missing looks up the caller chain and returns a local variable, can be abused, but sometimes useful like in emacs).

@batkins you can use the HTML pre tags for code formatting

-- Matthias Georgi


My rcr.rb file contains:

 # By default class Binding has no methods at all !
 class Binding
  # Evaluate a Ruby source code string in the binding context
  def eval( str )
    Kernel.eval( str, self)
  end
  # Returns the self in the binding context
  def self()
    eval( "self")
  end
  # Returns the local variables defined in the binding context
  def local_variables()
    eval( "local_variables")
  end
  # Returns the Method that was active, if any, when the binding was created
  #def method() ...???...
  # Returns the Proc that was active, if any, when the binding was created
  #def proc() ... ??? ...
  # Returns the call stack, same format as Kernel##caller()
  def caller( skip = 0 )
    eval( "caller( #{skip})")
  end
  # Returns the value of some variable
  def []( x )
    eval( x.to_s())
  end
  # Set the value of some lvalue
  def []=( l, v )
    eval( "proc {|v| #{l} = v").call( v)
  end
  # Returns the nature of something, nil if that thing is not defined.
  def defined?( x )
    eval( "defined? #{x}")
  end
 end

-- JeanHuguesRobert


Strongly opposed 0
Opposed 0
Neutral 0
In favor 11
Strongly advocate 3
ruby picture
If you have registered at RCRchive, you may now sign in below. If you have not registered, you may sign up for a username and password. Registering enables you to submit new RCRs, and vote and leave comments on existing RCRs.
Your username:
Your password:

ruby picture

Powered by .