From: nobu.nakada@... Date: 2001-12-14T00:53:10+09:00 Subject: [ruby-dev:15434] [EXP] private instance variable なかだです。 ふと思い立って以前話にあがっていたprivate instance variable(で いいんだっけ)を作ってみました。別クラスで定義したものにアクセス する手段がないとか、module_evalの中で定義したメソッドでは外側の 名前になってしまうとか、かなり手抜きですが参考までに。 Index: parse.y =================================================================== RCS file: /cvs/ruby/src/ruby/parse.y,v retrieving revision 1.136 diff -u -2 -p -r1.136 parse.y --- parse.y 2001/12/11 03:48:08 1.136 +++ parse.y 2001/12/13 15:24:29 @@ -96,4 +96,5 @@ static stack_type cmdarg_stack = 0; #define CMDARG_P() (cmdarg_stack&1) +static VALUE nest_scope; static int class_nest = 0; static int in_single = 0; @@ -1413,4 +1414,5 @@ primary : literal yyerror("class definition in method body"); class_nest++; + rb_ary_push(nest_scope, ID2SYM($2)); local_push(); $$ = ruby_sourceline; @@ -1422,4 +1424,5 @@ primary : literal nd_set_line($$, $4); local_pop(); + rb_ary_pop(nest_scope); class_nest--; } @@ -1451,4 +1454,5 @@ primary : literal yyerror("module definition in method body"); class_nest++; + rb_ary_push(nest_scope, ID2SYM($2)); local_push(); $$ = ruby_sourceline; @@ -1459,4 +1463,5 @@ primary : literal $$ = NEW_MODULE($2, $4); nd_set_line($$, $3); + rb_ary_pop(nest_scope); local_pop(); class_nest--; @@ -2146,5 +2151,13 @@ yycompile(f, line) ruby_sourcefile = f; ruby_in_compile = 1; + if (!nest_scope) { + nest_scope = rb_ary_new(); + rb_global_variable(&nest_scope); + } + else { + rb_ary_clear(nest_scope); + } n = yyparse(); + rb_ary_clear(nest_scope); ruby_debug_lines = 0; compile_for_eval = 0; @@ -3804,6 +3817,21 @@ yylex() if (tok()[1] == '@') result = tCVAR; - else + else { + if (tok()[1] == '_' && tok()[2]) { + VALUE scope = 0; + if (in_def && RARRAY(nest_scope)->len) { + scope = rb_ary_join(nest_scope, rb_str_new2("::")); + } + else if (compile_for_eval && RNODE(scope = ruby_frame->cbase)->nd_next) { + scope = rb_class_path(RNODE(scope)->nd_clss); + } + if (scope) { + char *s = RSTRING(scope)->ptr; + tokadd('@'); + while (*s) tokadd(*s++); + } + } result = tIVAR; + } break; @@ -5152,4 +5180,14 @@ rb_intern(name) else { id |= ID_INSTANCE; + if (name[1] == '_' && name[2]) { + while (*m && *m != '@') { + if (!is_identchar(*m)) { + id = ID_JUNK; + break; + } + m++; + } + goto id_new; + } } m++; @@ -5195,4 +5233,5 @@ rb_intern(name) } if (*m) id = ID_JUNK; + id_new: id |= ++last_id << ID_SCOPE_SHIFT; id_regist: -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦