Method_missing in Ruby 1.9.0

e$B=uED$G$9!#e(B

e$B<!$N%9%/%j%W%H$,!"e(Bruby 1.9.0 (2006-09-03)e$B$Ge(B
falsee$B$H=PNO$5$l$^$9!#e(B
class Foo
def method_missing(id, *arg)
p id # => false
end
end

foo = Foo.new
foo.visible = true

e$B<B9T7k2Le(B
W: ~/work>ruby19 -v mm.rb
ruby 1.9.0 (2006-09-03) [i386-cygwin]
false
W: ~/work>ruby -v mm.rb
ruby 1.8.5 (2006-09-01) [i386-cygwin]
:visible=

e$B=uEDe(B e$B2m5*e(B

[email protected]$G$9!#e(B

At Sun, 3 Sep 2006 09:55:59 +0900,
Masaki S. wrote in [ruby-dev:29420]:

e$B<!$N%9%/%j%W%H$,!"e(Bruby 1.9.0 (2006-09-03)e$B$Ge(B falsee$B$H=PNO$5$l$^$9!#e(B
class Foo
def method_missing(id, *arg)
p id # => false
end
end

foo = Foo.new
foo.visible = true

e$B$?$^$?$^e(Bfalse(== 0)[email protected]$1$G!"<B:]$K$OITDjCM$G$9$M!#e(B

Index: gc.c

RCS file: /cvs/ruby/src/ruby/gc.c,v
retrieving revision 1.248
diff -p -U 2 -r1.248 gc.c
— gc.c 2 Sep 2006 15:05:27 -0000 1.248
+++ gc.c 3 Sep 2006 01:12:58 -0000
@@ -1382,5 +1382,5 @@ garbage_collect(void)
#endif
rb_gc_mark_threads();

  • rb_gc_mark_symbols();
  • rb_gc_mark_symbols(0);

    /* mark protected global variables */
    Index: intern.h
    ===================================================================
    RCS file: /cvs/ruby/src/ruby/intern.h,v
    retrieving revision 1.199
    diff -p -U 2 -r1.199 intern.h
    — intern.h 31 Aug 2006 08:24:36 -0000 1.199
    +++ intern.h 3 Sep 2006 01:12:33 -0000
    @@ -259,4 +259,5 @@ int ruby_cleanup(int);
    int ruby_exec(void);
    void rb_gc_mark_threads(void);
    +void rb_gc_mark_symbols(int);
    void rb_thread_start_timer(void);
    void rb_thread_stop_timer(void);
    Index: parse.y
    ===================================================================
    RCS file: /cvs/ruby/src/ruby/parse.y,v
    retrieving revision 1.456
    diff -p -U 2 -r1.456 parse.y
    — parse.y 2 Sep 2006 15:05:27 -0000 1.456
    +++ parse.y 3 Sep 2006 05:10:38 -0000
    @@ -6030,5 +6030,4 @@ parser_yylex(struct parser_params *parse
    }
    if (c == ‘>’) {

  •   enum lex_state_e state = lex_state;
      lex_state = EXPR_ARG;
      return tLAMBDA;
    

@@ -8379,4 +8378,13 @@ rb_symname_p(const char *name)
}

+static void
+register_symid(VALUE sym, ID id)
+{

  • RBASIC(sym)->klass = rb_cSymbol;
  • OBJ_FREEZE(sym);
  • st_add_direct(global_symbols.sym_id, (st_data_t)sym, id);
  • st_add_direct(global_symbols.id_sym, id, (st_data_t)sym);
    +}

ID
rb_intern2(const char *name, long len)
@@ -8451,8 +8459,5 @@ rb_intern2(const char *name, long len)
id |= ++global_symbols.last_id << ID_SCOPE_SHIFT;
id_register:

  • RBASIC(sym)->klass = rb_cSymbol;
  • OBJ_FREEZE(sym);
  • st_add_direct(global_symbols.sym_id, (st_data_t)sym, id);
  • st_add_direct(global_symbols.id_sym, id, (st_data_t)sym);
  • register_symid(sym, id);
    return id;
    }
    @@ -8467,12 +8472,25 @@ VALUE
    rb_id2sym(ID id)
    {
  • VALUE data;
  • VALUE sym;

  • st_data_t data;

    if (st_lookup(global_symbols.id_sym, id, &data)) {

  • if (!RBASIC(data)->klass) {
  •   RBASIC(data)->klass = rb_cSymbol;
    
  • sym = (VALUE)data;
  • if (!RBASIC(sym)->klass) {
  •   RBASIC(sym)->klass = rb_cSymbol;
    
    }
  • return data;
    }
  • else {
  • if (!is_attrset_id(id)) return Qnil;
  • id &= ~ID_SCOPE_MASK;
  • if (!st_lookup(global_symbols.id_sym, (id | ID_LOCAL), &data) &&
  •   !st_lookup(global_symbols.id_sym, (id | ID_CONST), &data)) {
    
  •   return Qnil;
    
  • }
  • sym = rb_str_dup((VALUE)data);
  • rb_str_cat(sym, “=”, 1);
  • register_symid(sym, (id | ID_ATTRSET));
  • }
  • return sym;
    }

@@ -8490,6 +8508,5 @@ const char *
rb_id2name(ID id)
{

  • const char *name;
  • st_data_t data;
  • VALUE sym;

    if (id < tLAST_TOKEN) {
    @@ -8502,24 +8519,7 @@ rb_id2name(ID id)
    }

  • if (st_lookup(global_symbols.id_sym, id, &data))
  • return RSTRING_PTR(data);
  • if (is_attrset_id(id)) {
  • ID id2 = (id & ~ID_SCOPE_MASK) | ID_LOCAL;
  •  again:
    
  • name = rb_id2name(id2);
  • if (name) {
  •   char *buf = ALLOCA_N(char, strlen(name)+2);
    
  •   strcpy(buf, name);
    
  •   strcat(buf, "=");
    
  •   rb_intern(buf);
    
  •   return rb_id2name(id);
    
  • }
  • if (is_local_id(id2)) {
  •   id2 = (id & ~ID_SCOPE_MASK) | ID_CONST;
    
  •   goto again;
    
  • }
  • sym = rb_id2sym(id);
  • if (!NIL_P(sym)) {
  • return RSTRING_PTR(sym);
    }
    return 0;