Undefine

tony summerfelt [mailto:snowzone5@hotmail.com] :

I think the best way to get the behaviour you want is to use a
hash.

it seems to be more work (and lines of code) than it needs to be
for just one variable.

i was surprised that ruby didn't have a simple undefine function.
and for the oo'ness of it, it could look like x.undefine. no more
x :slight_smile:

Well, there's a problem with that. In Ruby, variables themselves are
not objects. They are merely labels for objects used in a particular
context.

What is it that you're trying to do -- codewise -- that seems to
require the ability to undefine a variable? There is probably a
different way to do what you want.

-austin

路路路

On Tue, 15 Jun 2004 00:17:55 +0900, you wrote:

--
austin ziegler * austin.ziegler@evault.com

i just posted a message of an perl example i ported to ruby.

and there IS a different way to do it...it was just longer...

路路路

On Tue, 15 Jun 2004 05:48:14 +0900, you wrote:

What is it that you're trying to do -- codewise -- that seems to
require the ability to undefine a variable? There is probably a
different way to do what you want.

tony summerfelt [mailto:snowzone5@hotmail.com] :

I think the best way to get the behaviour you want is to use a
hash.

it seems to be more work (and lines of code) than it needs to be
for just one variable.

i was surprised that ruby didn't have a simple undefine function.
and for the oo'ness of it, it could look like x.undefine. no more
x :slight_smile:

Well, there's a problem with that. In Ruby, variables themselves are
not objects. They are merely labels for objects used in a particular
context.

As a side note:
That variables are not objects is somehow an issue I believe.
There are a lot of methods that deal with variables. So far these
methods are not OO.
See http://www.c2.com/cgi/wiki?SinisterSchemeSampleInRuby for
some starting point for implementing a Variable class.

EOM. Yours,
JeanHuguesRobert

路路路

At 05:48 15/06/2004 +0900, you wrote:

On Tue, 15 Jun 2004 00:17:55 +0900, you wrote:

What is it that you're trying to do -- codewise -- that seems to
require the ability to undefine a variable? There is probably a
different way to do what you want.

-austin
--
austin ziegler * austin.ziegler@evault.com

-------------------------------------------------------------------------
Web: @jhr is virteal, virtually real
Phone: +33 (0) 4 92 27 74 17

Jean-Hugues ROBERT wrote:

As a side note:
That variables are not objects is somehow an issue I believe.
There are a lot of methods that deal with variables. So far these
methods are not OO.
See http://www.c2.com/cgi/wiki?SinisterSchemeSampleInRuby for
some starting point for implementing a Variable class.

I don't see a big need for Variable objects, but some interesting methods on a binding object *would* be interesting. E.g.

    binding.bind(:var, value)
    binding.lookup(:var)
    binding.unbind(:var)
    binding.names
    binding.each { |var_name, value| ... }

Or ... make binding ducktypeable with a hash (i.e. support hash-like methods).

路路路

--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

Jean-Hugues ROBERT wrote:

As a side note:
That variables are not objects is somehow an issue I believe.
There are a lot of methods that deal with variables. So far these
methods are not OO.
See http://www.c2.com/cgi/wiki?SinisterSchemeSampleInRuby for
some starting point for implementing a Variable class.

I don't see a big need for Variable objects, but some interesting methods on a binding object *would* be interesting. E.g.

I am working on a RCR to have free/bound variables
and some "match" operator.
A variable class makes sense in that context.

  binding.bind(:var, value)
  binding.lookup(:var)
  binding.unbind(:var)
  binding.names
  binding.each { |var_name, value| ... }

Or ... make binding ducktypeable with a hash (i.e. support hash-like methods).

--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

For what it is worth, here is my additions to the Binding class
in my rcr.rb file (feel free to fill the holes...).

Yours,

JeanHuguesRobert

class Continuation

  # Thanks to Florian Gross in ruby-talk ML msg 103312.
  def self.create( *args, &block )
    cc = nil;
    result = callcc { |c|
      cc = c;
      block.call( cc) if block and args.empty?
    }
    result ||= args
    return *[cc, *result]
  end

end

# 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 value of 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

  # Thanks to Florian Gross in ruby-talk ML msg 103312.
  # This method returns the binding of the method that called your
  # method. Don't use it when you're not inside a method.

路路路

At 15:41 15/06/2004 +0900, you wrote:
  #
  # It's used like this:
  # def inc_counter
  # Binding.of_caller do |binding|
  # eval("counter += 1", binding)
  # end
  # end
  # counter = 0
  # 2.times { inc_counter }
  # counter # => 2
  #
  # You will have to put the whole rest of your method into the
  # block that you pass into this method. If you don't do this
  # an Exception will be raised. Because of the way that this is
  # implemented it has to be done this way.
  def self.of_caller( &block )
    old_critical = Thread.critical
    Thread.critical = true
    count = 0
    cc, result, error = Continuation.create( nil, nil)
    error.call if error
    tracer = lambda do |*args|
      type, context = args[0], args[4]
      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)
        end
      elsif type != "line"
        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 ) })
      end
    end
    unless result
      set_trace_func( tracer)
      return nil
    else
      Thread.critical = old_critical
      yield result
    end
  end

end

-------------------------------------------------------------------------
Web: http://hdl.handle.net/1030.37/1.1
Phone: +33 (0) 4 92 27 74 17