The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Binding#remove_local_variable

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Eric Hodel

Posts: 660
Nickname: drbrain
Registered: Mar, 2006

Eric Hodel is a long-time Rubyist and co-founder of Seattle.rb.
Binding#remove_local_variable Posted: Apr 23, 2009 6:29 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Eric Hodel.
Original Post: Binding#remove_local_variable
Feed Title: Segment7
Feed URL: http://blog.segment7.net/articles.rss
Feed Description: Posts about and around Ruby, MetaRuby, ruby2c, ZenTest and work at The Robot Co-op.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Eric Hodel
Latest Posts From Segment7

Advertisement
require 'rubygems'
require 'inline'

class Binding
  inline do |builder|
    builder.include '"node.h"'
    builder.include '"env.h"'

    ##
    # struct BLOCK isn't in any header, so include it here.

    builder.prefix <<-C
struct BLOCK {
  NODE *var;
  NODE *body;
  VALUE self;
  struct FRAME frame;
  struct SCOPE *scope;
  VALUE klass;
  NODE *cref;
  int iter;
  int vmode;
  int flags;
  int uniq;
  struct RVarmap *dyna_vars;
  VALUE orig_thread;
  VALUE wrapper;
  VALUE block_obj;
  struct BLOCK *outer;
  struct BLOCK *prev;
};
    C

    ##
    # :method: remove_local_variable
    #
    # Removes the local variable +name+ and replaces it with nil.
    #
    # Ordinarily if a local variable didn't exist it would raise
    # NoMethodError, but currently after #remove_local_variable it doesn't, it
    # just returns nil.
    #
    # In order to make this behave correctly, block->body would need to be
    # walked, duping nodes (so as not to affect future invocations of this
    # method) and replacing the LVAR nodes with VCALL nodes.
    #
    # That's just too much work for 17:15, though.  Maybe tomorrow.

    builder.c <<-C
VALUE remove_local_variable(VALUE name) {
  struct BLOCK *block;
  struct SCOPE *scope;
  ID name_id;
  ID *local_table;
  int i, n;
  VALUE entry;

  name_id = SYM2ID(name);

  Data_Get_Struct(self, struct BLOCK, block);

  scope = block->scope;
  local_table = scope->local_tbl;

  if (local_table) {
    n = *local_table++;
    for (i = 2; i < n; i++) { /* skip $_ and $~ */
      if (!rb_is_local_id(local_table[i])) continue; /* skip flip states */
      if (local_table[i] == name_id) {
        entry = scope->local_vars[i];
        local_table[i] = (ID)NULL;
        scope->local_vars[i] = Qnil;
        return entry;
      }
    }
  }

  return Qnil;
}
    C

  end
end

a = :my_value

p :lvar_a => a

b = binding
p :remove_local_variable_says => b.remove_local_variable(:a)

p :lvar_a => a # TODO raise exception

Read: Binding#remove_local_variable

Topic: QA, Developers, and Agile Previous Topic   Next Topic Topic: Flex source control in Amethyst projects

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use