diff --git a/ChangeLog b/ChangeLog index 7195394dd5..0f30916676 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +Wed Nov 17 02:40:40 1999 Yukihiro Matsumoto + + * io.c (Init_IO): $defout (alias of $>) added. + +Tue Nov 16 09:47:14 1999 Yukihiro Matsumoto + + * lib/pstore.rb: add mutual lock using symlink. + +Mon Nov 15 16:50:34 1999 Yukihiro Matsumoto + + * enum.c (enum_grep): non matching grep returns an empty array, no + longer returns nil. + + * enum.c (enum_grep): grep with block returns collection of + evaluated values of block over matched elements. + +Mon Nov 15 04:50:33 1999 Koji Arai + + * re.c (rb_reg_source): should not call rb_reg_expr_str() + everytime. + +Sat Nov 13 07:34:18 1999 Yukihiro Matsumoto + + * variable.c (rb_mod_constants): traverse superclasses to collect + constants (shared variables). + + * eval.c (assign): modified for shared variables. + + * eval.c (rb_eval): search nested scope, then superclasses to + assign shared variables within methods. + + * eval.c (rb_eval): remove warnings from constants modification, + becase they are no longer constants. + + * parse.y (node_assign): modified for shared variables. + + * parse.y (assignable): allow constant assignment in methods; + constants should be called `shared variable'. + Wed Nov 10 21:54:11 1999 EGUCHI Osamu * hash.c (rb_any_cmp): Fixed return without value. diff --git a/ToDo b/ToDo index ce2459a12d..f39a018348 100644 --- a/ToDo +++ b/ToDo @@ -3,12 +3,14 @@ Language Spec. - def foo; .. rescue .. end - compile time string concatenation, "hello" "world" => "helloworld" - rescue modifier; a rescue b => begin a rescue; b end +- assignable constant, which now should be called shared variable. +- class variable (prefix?) -- done by shared variable * objectify symbols * objectify characters * ../... outside condition invokes operator method too. +* ... inside condition turns off just before right condition.??? * %w(a\ b\ c abc) => ["a b c", "abc"] -* package or access control for global variables -* class variable (prefix?) +* package or access control for global variables?? * named arguments like foo(nation:="german") or foo(nation: "german"). * method to retrieve argument information (need new C API) * multiple return values, yield values. maybe incompatible ??? @@ -21,6 +23,7 @@ Hacking Interpreter - use eban's fnmatch - RUBYOPT environment variable +- alias $defout $> * non-blocking open (e.g. for named pipe) for thread * avoid blocking with gethostbyname/gethostbyaddr * objectify interpreters @@ -36,6 +39,7 @@ Standard Libraries - Array#{first,last,at} - Dir.glob(pat){|f|...} - sprintf/printf's $ to specify argument order +* debugger for thread programming * Dir.glob("**/*.c") ala zsh * Struct::new([name,]member,...) ?? * String#scanf(?) diff --git a/class.c b/class.c index 32dc0e1372..6ffd328215 100644 --- a/class.c +++ b/class.c @@ -130,7 +130,7 @@ rb_define_class_under(outer, name, super) id = rb_intern(name); klass = rb_define_class_id(id, super); - rb_const_set(outer, id, klass); + rb_shvar_set(outer, id, klass); rb_set_class_path(klass, outer, name); return klass; @@ -186,7 +186,7 @@ rb_define_module_under(outer, name) id = rb_intern(name); module = rb_define_module_id(id); - rb_const_set(outer, id, module); + rb_shvar_set(outer, id, module); rb_set_class_path(module, outer, name); return module; diff --git a/enum.c b/enum.c index 05194c1f52..008e0a4136 100644 --- a/enum.c +++ b/enum.c @@ -33,11 +33,11 @@ grep_i(i, arg) } static VALUE -grep_iter_i(i, pat) - VALUE i, pat; +grep_iter_i(i, arg) + VALUE i, *arg; { - if (RTEST(rb_funcall(pat, id_eqq, 1, i))) { - rb_yield(i); + if (RTEST(rb_funcall(arg[0], id_eqq, 1, i))) { + rb_ary_push(arg[1], rb_yield(i)); } return Qnil; } @@ -46,19 +46,16 @@ static VALUE enum_grep(obj, pat) VALUE obj, pat; { + VALUE tmp, arg[2]; + + arg[0] = pat; arg[1] = tmp = rb_ary_new(); if (rb_iterator_p()) { rb_iterate(rb_each, obj, grep_iter_i, pat); - return obj; } else { - VALUE tmp, arg[2]; - - arg[0] = pat; arg[1] = tmp = rb_ary_new(); rb_iterate(rb_each, obj, grep_i, (VALUE)arg); - - if (RARRAY(tmp)->len == 0) return Qnil; - return tmp; } + return tmp; } struct find_arg { diff --git a/eval.c b/eval.c index eb3687fd08..de3c73e376 100644 --- a/eval.c +++ b/eval.c @@ -1300,7 +1300,7 @@ superclass(self, node) } static VALUE -ev_const_defined(cref, id) +ev_shvar_defined(cref, id) NODE *cref; ID id; { @@ -1315,11 +1315,11 @@ ev_const_defined(cref, id) } cbase = cbase->nd_next; } - return rb_const_defined(cref->nd_clss, id); + return rb_shvar_defined(cref->nd_clss, id); } static VALUE -ev_const_get(cref, id) +ev_shvar_get(cref, id) NODE *cref; ID id; { @@ -1329,13 +1329,34 @@ ev_const_get(cref, id) while (cbase && cbase->nd_clss != rb_cObject) { struct RClass *klass = RCLASS(cbase->nd_clss); - if (klass->iv_tbl && - st_lookup(klass->iv_tbl, id, &result)) { + if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, &result)) { return result; } cbase = cbase->nd_next; } - return rb_const_get(cref->nd_clss, id); + return rb_shvar_get(cref->nd_clss, id); +} + +static VALUE +ev_shvar_set(cref, id, val) + NODE *cref; + ID id; + VALUE val; +{ + NODE *cbase = cref; + VALUE tmp; + + while (cbase && cbase->nd_clss != rb_cObject) { + struct RClass *klass = RCLASS(cbase->nd_clss); + + if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, 0)) { + st_insert(klass->iv_tbl, id, val); + return val; + } + cbase = cbase->nd_next; + } + rb_shvar_assign(cbase->nd_clss, id, val); + return val; } static VALUE @@ -1352,17 +1373,17 @@ rb_mod_nesting() } static VALUE -rb_mod_s_constants() +rb_mod_s_shvars() { NODE *cbase = (NODE*)ruby_frame->cbase; VALUE ary = rb_ary_new(); while (cbase && cbase->nd_clss != rb_cObject) { - rb_mod_const_at(cbase->nd_clss, ary); + rb_mod_shvar_at(cbase->nd_clss, ary); cbase = cbase->nd_next; } - rb_mod_const_of(((NODE*)ruby_frame->cbase)->nd_clss, ary); + rb_mod_shvar_of(((NODE*)ruby_frame->cbase)->nd_clss, ary); return ary; } @@ -1585,7 +1606,7 @@ is_defined(self, node, buf) break; case NODE_CVAR: - if (ev_const_defined((NODE*)ruby_frame->cbase, node->nd_vid)) { + if (ev_shvar_defined((NODE*)ruby_frame->cbase, node->nd_vid)) { return "constant"; } break; @@ -1601,7 +1622,7 @@ is_defined(self, node, buf) switch (TYPE(val)) { case T_CLASS: case T_MODULE: - if (rb_const_defined_at(val, node->nd_mid)) + if (rb_shvar_defined_at(val, node->nd_mid)) return "constant"; default: if (rb_method_boundp(val, node->nd_mid, 1)) { @@ -2392,13 +2413,15 @@ rb_eval(self, node) rb_raise(rb_eTypeError, "no class/module to define constant"); } result = rb_eval(self, node->nd_value); - /* check for static scope constants */ - if (RTEST(ruby_verbose) && - ev_const_defined((NODE*)ruby_frame->cbase, node->nd_vid)) { - rb_warn("already initialized constant %s", - rb_id2name(node->nd_vid)); + ev_shvar_set((NODE*)ruby_frame->cbase, node->nd_vid, result); + break; + + case NODE_CDECL: + if (NIL_P(ruby_class)) { + rb_raise(rb_eTypeError, "no class/module to define constant"); } - rb_const_set(ruby_class, node->nd_vid, result); + result = rb_eval(self, node->nd_value); + rb_shvar_set(ruby_class, node->nd_vid, result); break; case NODE_LVAR: @@ -2421,7 +2444,7 @@ rb_eval(self, node) break; case NODE_CVAR: - result = ev_const_get((NODE*)ruby_frame->cbase, node->nd_vid); + result = ev_shvar_get((NODE*)ruby_frame->cbase, node->nd_vid); break; case NODE_BLOCK_ARG: @@ -2448,12 +2471,12 @@ rb_eval(self, node) default: return rb_funcall(klass, node->nd_mid, 0, 0); } - result = rb_const_get_at(klass, node->nd_mid); + result = rb_shvar_get(klass, node->nd_mid); } break; case NODE_COLON3: - result = rb_const_get_at(rb_cObject, node->nd_mid); + result = rb_shvar_get(rb_cObject, node->nd_mid); break; case NODE_NTH_REF: @@ -2754,12 +2777,12 @@ rb_eval(self, node) } klass = 0; - if (rb_const_defined_at(ruby_class, node->nd_cname) && + if (rb_shvar_defined_at(ruby_class, node->nd_cname) && (ruby_class != rb_cObject || !rb_autoload_defined(node->nd_cname))) { - klass = rb_const_get_at(ruby_class, node->nd_cname); + klass = rb_shvar_get(ruby_class, node->nd_cname); } - if (ruby_wrapper && rb_const_defined_at(rb_cObject, node->nd_cname)) { - klass = rb_const_get_at(rb_cObject, node->nd_cname); + if (ruby_wrapper && rb_shvar_defined_at(rb_cObject, node->nd_cname)) { + klass = rb_shvar_get(rb_cObject, node->nd_cname); } if (klass) { if (TYPE(klass) != T_CLASS) { @@ -2787,7 +2810,7 @@ rb_eval(self, node) else { if (!super) super = rb_cObject; klass = rb_define_class_id(node->nd_cname, super); - rb_const_set(ruby_class, node->nd_cname, klass); + rb_shvar_set(ruby_class, node->nd_cname, klass); rb_set_class_path(klass,ruby_class,rb_id2name(node->nd_cname)); } if (ruby_wrapper) { @@ -2807,13 +2830,13 @@ rb_eval(self, node) rb_raise(rb_eTypeError, "no outer class/module"); } module = 0; - if (rb_const_defined_at(ruby_class, node->nd_cname) && + if (rb_shvar_defined_at(ruby_class, node->nd_cname) && (ruby_class != rb_cObject || !rb_autoload_defined(node->nd_cname))) { - module = rb_const_get_at(ruby_class, node->nd_cname); + module = rb_shvar_get(ruby_class, node->nd_cname); } - if (ruby_wrapper && rb_const_defined_at(rb_cObject, node->nd_cname)) { - module = rb_const_get_at(rb_cObject, node->nd_cname); + if (ruby_wrapper && rb_shvar_defined_at(rb_cObject, node->nd_cname)) { + module = rb_shvar_get(rb_cObject, node->nd_cname); } if (module) { if (TYPE(module) != T_MODULE) { @@ -2826,7 +2849,7 @@ rb_eval(self, node) } else { module = rb_define_module_id(node->nd_cname); - rb_const_set(ruby_class, node->nd_cname, module); + rb_shvar_set(ruby_class, node->nd_cname, module); rb_set_class_path(module,ruby_class,rb_id2name(node->nd_cname)); } if (ruby_wrapper) { @@ -3368,7 +3391,11 @@ assign(self, lhs, val, check) break; case NODE_CASGN: - rb_const_set(ruby_class, lhs->nd_vid, val); + ev_shvar_set((NODE*)ruby_frame->cbase, lhs->nd_vid, val); + break; + + case NODE_CDECL: + rb_shvar_set(ruby_class, lhs->nd_vid, val); break; case NODE_MASGN: @@ -5317,7 +5344,9 @@ Init_eval() rb_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2); rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0); - rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, 0); + rb_define_singleton_method(rb_cModule, "shared_variables", rb_mod_s_shvars, 0); + /* to be removed at 1.6 */ + rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_shvars, 0); rb_define_singleton_method(ruby_top_self, "include", top_include, -1); rb_define_singleton_method(ruby_top_self, "public", top_public, -1); diff --git a/intern.h b/intern.h index 8c303e9455..33547cf07b 100644 --- a/intern.h +++ b/intern.h @@ -220,7 +220,7 @@ int yyparse _((void)); ID rb_id_attrset _((ID)); void rb_parser_append_print _((void)); void rb_parser_while_loop _((int, int)); -int rb_is_const_id _((ID)); +int rb_is_shvar_id _((ID)); int rb_is_instance_id _((ID)); VALUE rb_backref_get _((void)); void rb_backref_set _((VALUE)); @@ -310,7 +310,6 @@ VALUE rb_f_autoload _((VALUE, VALUE, VALUE)); void rb_gc_mark_global_tbl _((void)); VALUE rb_f_trace_var _((int, VALUE*)); VALUE rb_f_untrace_var _((int, VALUE*)); -VALUE rb_gvar_set2 _((const char*, VALUE)); VALUE rb_f_global_variables _((void)); void rb_alias_variable _((ID, ID)); void rb_clone_generic_ivar _((VALUE,VALUE)); @@ -322,13 +321,17 @@ VALUE rb_ivar_set _((VALUE, ID, VALUE)); VALUE rb_ivar_defined _((VALUE, ID)); VALUE rb_obj_instance_variables _((VALUE)); VALUE rb_obj_remove_instance_variable _((VALUE, VALUE)); -VALUE rb_mod_const_at _((VALUE, VALUE)); -VALUE rb_mod_constants _((VALUE)); -VALUE rb_mod_const_of _((VALUE, VALUE)); -VALUE rb_mod_remove_const _((VALUE, VALUE)); -int rb_const_defined_at _((VALUE, ID)); +VALUE rb_mod_shvar_at _((VALUE, VALUE)); +VALUE rb_mod_shvars _((VALUE)); +VALUE rb_mod_shvar_of _((VALUE, VALUE)); +VALUE rb_mod_remove_shvar _((VALUE, VALUE)); +int rb_shvar_defined_at _((VALUE, ID)); int rb_autoload_defined _((ID)); -int rb_const_defined _((VALUE, ID)); +int rb_shvar_defined _((VALUE, ID)); +VALUE rb_shvar_get _((VALUE, ID)); +VALUE rb_shvar_get_at _((VALUE, ID)); +void rb_shvar_set _((VALUE, ID, VALUE)); +VALUE rb_mod_shared_variables _((VALUE)); /* version.c */ void ruby_show_version _((void)); void ruby_show_copyright _((void)); diff --git a/io.c b/io.c index 61052b3beb..d03277f04f 100644 --- a/io.c +++ b/io.c @@ -3283,6 +3283,7 @@ Init_IO() rb_define_hooked_variable("$stderr", &rb_stderr, 0, set_stderr); rb_defout = rb_stdout; rb_define_hooked_variable("$>", &rb_defout, 0, rb_io_defset); + rb_define_hooked_variable("$defout", &rb_defout, 0, rb_io_defset); rb_define_global_const("STDIN", rb_stdin); rb_define_global_const("STDOUT", rb_stdout); diff --git a/lib/pstore.rb b/lib/pstore.rb index 2aa9864b58..cc90207aa3 100644 --- a/lib/pstore.rb +++ b/lib/pstore.rb @@ -78,6 +78,16 @@ class PStore begin @transaction = true value = file = nil + lock = @filename + ".lock" + loop do + begin + File::symlink("pstore::#$$", lock) + break + rescue Errno::EEXIST + rescue + sleep 1 + end + end begin File::open(@filename, "r") do |file| @table = Marshal.load(file) @@ -112,6 +122,7 @@ class PStore ensure @table = nil @transaction = false + File::unlink(lock) end value end diff --git a/lib/singleton.rb b/lib/singleton.rb index 8167a01aa8..4aea574e7a 100644 --- a/lib/singleton.rb +++ b/lib/singleton.rb @@ -14,6 +14,7 @@ module Singleton def Singleton.append_features(klass) klass.private_class_method(:new) klass.instance_eval %{ + @__instance__ = nil def instance unless @__instance__ @__instance__ = new diff --git a/node.h b/node.h index ea44a454d5..e402d0f944 100644 --- a/node.h +++ b/node.h @@ -49,6 +49,7 @@ enum node_type { NODE_GASGN, NODE_IASGN, NODE_CASGN, + NODE_CDECL, NODE_OP_ASGN1, NODE_OP_ASGN2, NODE_OP_ASGN_AND, @@ -260,6 +261,7 @@ typedef struct RNode { #define NEW_DASGN_PUSH(v,val) rb_node_newnode(NODE_DASGN_PUSH,v,val,0); #define NEW_IASGN(v,val) rb_node_newnode(NODE_IASGN,v,val,0) #define NEW_CASGN(v,val) rb_node_newnode(NODE_CASGN,v,val,0) +#define NEW_CDECL(v,val) rb_node_newnode(NODE_CDECL,v,val,0) #define NEW_OP_ASGN1(p,id,a) rb_node_newnode(NODE_OP_ASGN1,p,id,a) #define NEW_OP_ASGN2(r,i,o,val) rb_node_newnode(NODE_OP_ASGN2,r,val,NEW_OP_ASGN22(i,o)) #define NEW_OP_ASGN22(i,o) rb_node_newnode(NODE_OP_ASGN2,i,o,rb_id_attrset(i)) diff --git a/object.c b/object.c index 9c5163a248..6314974e3f 100644 --- a/object.c +++ b/object.c @@ -687,25 +687,25 @@ rb_mod_attr_accessor(argc, argv, klass) } static VALUE -rb_mod_const_get(mod, name) +rb_mod_shvar_get(mod, name) VALUE mod, name; { - return rb_const_get_at(mod, rb_to_id(name)); + return rb_shvar_get(mod, rb_to_id(name)); } static VALUE -rb_mod_const_set(mod, name, value) +rb_mod_shvar_set(mod, name, value) VALUE mod, name, value; { - rb_const_set(mod, rb_to_id(name), value); + rb_shvar_set(mod, rb_to_id(name), value); return value; } static VALUE -rb_mod_const_defined(mod, name) +rb_mod_shvar_defined(mod, name) VALUE mod, name; { - return rb_const_defined_at(mod, rb_to_id(name)); + return rb_shvar_defined_at(mod, rb_to_id(name)); } static VALUE @@ -1069,11 +1069,17 @@ Init_Object() rb_define_method(rb_cModule, "protected_instance_methods", rb_class_protected_instance_methods, -1); rb_define_method(rb_cModule, "private_instance_methods", rb_class_private_instance_methods, -1); - rb_define_method(rb_cModule, "constants", rb_mod_constants, 0); - rb_define_method(rb_cModule, "const_get", rb_mod_const_get, 1); - rb_define_method(rb_cModule, "const_set", rb_mod_const_set, 2); - rb_define_method(rb_cModule, "const_defined?", rb_mod_const_defined, 1); - rb_define_private_method(rb_cModule, "remove_const", rb_mod_remove_const, 1); + rb_define_method(rb_cModule, "shared_variable", rb_mod_shvars, 0); + rb_define_method(rb_cModule, "shared_variable_get", rb_mod_shvar_get, 1); + rb_define_method(rb_cModule, "shared_variable_set", rb_mod_shvar_set, 2); + rb_define_method(rb_cModule, "shared_variable_defined?", rb_mod_shvar_defined, 1); + rb_define_private_method(rb_cModule, "remove_shared_variable", rb_mod_remove_shvar, 1); + /* to be remove at 1.6*/ + rb_define_method(rb_cModule, "constants", rb_mod_shvars, 0); + rb_define_method(rb_cModule, "const_get", rb_mod_shvar_get, 1); + rb_define_method(rb_cModule, "const_set", rb_mod_shvar_set, 2); + rb_define_method(rb_cModule, "const_defined?", rb_mod_shvar_defined, 1); + rb_define_private_method(rb_cModule, "remove_const", rb_mod_remove_shvar, 1); rb_define_private_method(rb_cModule, "method_added", rb_obj_dummy, 1); rb_define_method(rb_cClass, "new", rb_class_new_instance, -1); diff --git a/parse.y b/parse.y index 435221d8d8..6368a646d4 100644 --- a/parse.y +++ b/parse.y @@ -26,14 +26,14 @@ #define ID_INSTANCE 0x02 #define ID_GLOBAL 0x03 #define ID_ATTRSET 0x04 -#define ID_CONST 0x05 +#define ID_SHARED 0x05 -#define is_id_notop(id) ((id)>LAST_TOKEN) -#define is_local_id(id) (is_id_notop(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL) -#define is_global_id(id) (is_id_notop(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL) -#define is_instance_id(id) (is_id_notop(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE) -#define is_attrset_id(id) (is_id_notop(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET) -#define is_const_id(id) (is_id_notop(id)&&((id)&ID_SCOPE_MASK)==ID_CONST) +#define is_notop_id(id) ((id)>LAST_TOKEN) +#define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL) +#define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL) +#define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE) +#define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET) +#define is_shared_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_SHARED) NODE *ruby_eval_tree_begin = 0; NODE *ruby_eval_tree = 0; @@ -1787,10 +1787,10 @@ yycompile(f) int n; if (!ruby_in_eval && rb_safe_level() == 0 && - rb_const_defined(rb_cObject, rb_intern("LINES__"))) { + rb_shvar_defined(rb_cObject, rb_intern("LINES__"))) { VALUE hash, fname; - hash = rb_const_get(rb_cObject, rb_intern("LINES__")); + hash = rb_shvar_get(rb_cObject, rb_intern("LINES__")); if (TYPE(hash) == T_HASH) { fname = rb_str_new2(f); ruby_debug_lines = rb_hash_aref(hash, fname); @@ -3715,7 +3715,7 @@ gettable(id) else if (is_instance_id(id)) { return NEW_IVAR(id); } - else if (is_const_id(id)) { + else if (is_shared_id(id)) { return NEW_CVAR(id); } rb_bug("invalid id for gettable"); @@ -3766,10 +3766,11 @@ assignable(id, val) else if (is_instance_id(id)) { lhs = NEW_IASGN(id, val); } - else if (is_const_id(id)) { + else if (is_shared_id(id)) { if (cur_mid || in_single) - yyerror("dynamic constant assignment"); - lhs = NEW_CASGN(id, val); + lhs = NEW_CASGN(id, val); + else + lhs = NEW_CDECL(id, val); } else { rb_bug("bad id for variable"); @@ -3854,8 +3855,9 @@ node_assign(lhs, rhs) case NODE_LASGN: case NODE_DASGN: case NODE_DASGN_PUSH: - case NODE_CASGN: case NODE_MASGN: + case NODE_CASGN: + case NODE_CDECL: lhs->nd_value = rhs; break; @@ -4494,7 +4496,7 @@ rb_intern(name) id = ID_ATTRSET; } else if (ISUPPER(name[0])) { - id = ID_CONST; + id = ID_SHARED; } else { id = ID_LOCAL; @@ -4546,12 +4548,19 @@ rb_id2name(id) return 0; } +int +rb_is_shared_id(id) + ID id; +{ + if (is_shared_id(id)) return Qtrue; + return Qfalse; +} + int rb_is_const_id(id) ID id; { - if (is_const_id(id)) return Qtrue; - return Qfalse; + return rb_is_shared_id(id); } int diff --git a/re.c b/re.c index 04d4978d3e..540ae2848d 100644 --- a/re.c +++ b/re.c @@ -275,10 +275,7 @@ static VALUE rb_reg_source(re) VALUE re; { - VALUE str = rb_str_new(0,0); - rb_reg_expr_str(str, RREGEXP(re)->str, RREGEXP(re)->len); - - return str; + return rb_str_new(RREGEXP(re)->str,RREGEXP(re)->len); } static VALUE diff --git a/ruby.c b/ruby.c index 45c15bdc99..5a1a58c89c 100644 --- a/ruby.c +++ b/ruby.c @@ -278,10 +278,10 @@ process_sflag() s[0] = '$'; if (p = strchr(s, '=')) { *p++ = '\0'; - rb_gvar_set2(s, rb_str_new2(p)); + rb_gv_set(s, rb_str_new2(p)); } else { - rb_gvar_set2(s, Qtrue); + rb_gv_set(s, Qtrue); } s[0] = '-'; } diff --git a/ruby.h b/ruby.h index 765fd75ee8..adbcff6c75 100644 --- a/ruby.h +++ b/ruby.h @@ -375,8 +375,8 @@ void rb_define_variable _((const char*,VALUE*)); void rb_define_virtual_variable _((const char*,VALUE(*)(),void(*)())); void rb_define_hooked_variable _((const char*,VALUE*,VALUE(*)(),void(*)())); void rb_define_readonly_variable _((const char*,VALUE*)); -void rb_define_const _((VALUE,const char*,VALUE)); -void rb_define_global_const _((const char*,VALUE)); +void rb_define_shared_variable _((VALUE,const char*,VALUE)); +void rb_define_global_shared_variable _((const char*,VALUE)); void rb_define_method _((VALUE,const char*,VALUE(*)(),int)); void rb_define_module_function _((VALUE,const char*,VALUE(*)(),int)); @@ -402,11 +402,10 @@ VALUE rb_funcall2 _((VALUE, ID, int, VALUE*)); VALUE rb_funcall3 _((VALUE, ID, int, VALUE*)); int rb_scan_args __((int, VALUE*, const char*, ...)); +VALUE rb_gv_set _((const char*, VALUE)); +VALUE rb_gv_get _((const char*)); VALUE rb_iv_get _((VALUE, const char*)); VALUE rb_iv_set _((VALUE, const char*, VALUE)); -VALUE rb_const_get _((VALUE, ID)); -VALUE rb_const_get_at _((VALUE, ID)); -void rb_const_set _((VALUE, ID, VALUE)); VALUE rb_equal _((VALUE,VALUE)); diff --git a/sample/rename.rb b/sample/rename.rb index cacb2b7508..2d1b62ea8f 100644 --- a/sample/rename.rb +++ b/sample/rename.rb @@ -268,7 +268,7 @@ gsub!(/\bscan_oct\b/,"ruby_scan_oct") gsub!(/\bconst_defined\b/,"rb_const_defined") gsub!(/\bconst_defined_at\b/,"rb_const_defined_at") gsub!(/\bconst_get\b/,"rb_const_get") -gsub!(/\bconst_get_at\b/,"rb_const_get_at") +gsub!(/\bconst_get_at\b/,"rb_const_get") gsub!(/\bconst_set\b/,"rb_const_set") gsub!(/\bf_autoload\b/,"rb_f_autoload") gsub!(/\bf_global_variables\b/,"rb_f_global_variables") diff --git a/struct.c b/struct.c index e22c539fac..50b273b5a4 100644 --- a/struct.c +++ b/struct.c @@ -161,7 +161,7 @@ make_struct(name, member, klass) else { char *cname = STR2CSTR(name); id = rb_intern(cname); - if (!rb_is_const_id(id)) { + if (!rb_is_shared_id(id)) { rb_raise(rb_eNameError, "identifier %s needs to be constant", cname); } nstr = rb_define_class_under(klass, cname, klass); diff --git a/variable.c b/variable.c index 7b273933ac..d66fa9915b 100644 --- a/variable.c +++ b/variable.c @@ -44,7 +44,7 @@ fc_i(key, value, res) VALUE path; char *name; - if (!rb_is_const_id(key)) return ST_CONTINUE; + if (!rb_is_shared_id(key)) return ST_CONTINUE; name = rb_id2name(key); if (res->path) { @@ -216,7 +216,7 @@ rb_autoload_id(id, filename) ID id; const char *filename; { - if (!rb_is_const_id(id)) { + if (!rb_is_shared_id(id)) { rb_raise(rb_eNameError, "autoload must be constant name", rb_id2name(id)); } @@ -630,7 +630,7 @@ rb_gvar_set(entry, val) } VALUE -rb_gvar_set2(name, val) +rb_gv_set(name, val) const char *name; VALUE val; { @@ -640,6 +640,16 @@ rb_gvar_set2(name, val) return rb_gvar_set(entry, val); } +VALUE +rb_gv_get(name) + const char *name; +{ + struct global_entry *entry; + + entry = rb_global_entry(global_id(name)); + return rb_gvar_get(entry); +} + VALUE rb_gvar_defined(entry) struct global_entry *entry; @@ -973,7 +983,7 @@ rb_obj_remove_instance_variable(obj, name) } VALUE -rb_const_get_at(klass, id) +rb_shvar_get_at(klass, id) VALUE klass; ID id; { @@ -983,7 +993,7 @@ rb_const_get_at(klass, id) return value; } if (klass == rb_cObject) { - return rb_const_get(klass, id); + return rb_shvar_get(klass, id); } rb_raise(rb_eNameError, "uninitialized constant %s::%s", RSTRING(rb_class_path(klass))->ptr, @@ -993,7 +1003,15 @@ rb_const_get_at(klass, id) VALUE -rb_const_get(klass, id) +rb_const_get_at(klass, id) + VALUE klass; + ID id; +{ + return rb_shvar_get_at(klass, id); +} + +VALUE +rb_shvar_get(klass, id) VALUE klass; ID id; { @@ -1008,7 +1026,7 @@ rb_const_get(klass, id) tmp = RCLASS(tmp)->super; } if (BUILTIN_TYPE(klass) == T_MODULE) { - return rb_const_get(rb_cObject, id); + return rb_shvar_get(rb_cObject, id); } /* pre-defined class */ @@ -1023,7 +1041,7 @@ rb_const_get(klass, id) module = rb_str_new2(modname); free(modname); rb_f_require(Qnil, module); - return rb_const_get(klass, id); + return rb_shvar_get(klass, id); } /* Uninitialized constant */ @@ -1037,13 +1055,21 @@ rb_const_get(klass, id) return Qnil; /* not reached */ } +VALUE +rb_const_get(klass, id) + VALUE klass; + ID id; +{ + return rb_shvar_get(klass, id); +} + static int -const_i(key, value, ary) +sv_i(key, value, ary) ID key; VALUE value; VALUE ary; { - if (rb_is_const_id(key)) { + if (rb_is_shared_id(key)) { VALUE kval = rb_str_new2(rb_id2name(key)); if (!rb_ary_includes(ary, kval)) { rb_ary_push(ary, kval); @@ -1053,20 +1079,20 @@ const_i(key, value, ary) } VALUE -rb_mod_remove_const(mod, name) +rb_mod_remove_shvar(mod, name) VALUE mod, name; { ID id = rb_to_id(name); VALUE val; - if (!rb_is_const_id(id)) { - rb_raise(rb_eNameError, "`%s' is not constant", rb_id2name(id)); + if (!rb_is_shared_id(id)) { + rb_raise(rb_eNameError, "`%s' is not shared variable", rb_id2name(id)); } if (RCLASS(mod)->iv_tbl && st_delete(ROBJECT(mod)->iv_tbl, &id, &val)) { return val; } - if (rb_const_defined_at(mod, id)) { + if (rb_shvar_defined_at(mod, id)) { rb_raise(rb_eNameError, "cannot remove %s::%s", rb_class2name(mod), rb_id2name(id)); } @@ -1075,6 +1101,13 @@ rb_mod_remove_const(mod, name) return Qnil; /* not reached */ } +VALUE +rb_mod_remove_const(mod, name) + VALUE mod, name; +{ + return rb_mod_remove_shvar(mod, name); +} + static int autoload_i(key, name, ary) ID key; @@ -1089,16 +1122,16 @@ autoload_i(key, name, ary) } VALUE -rb_mod_const_at(mod, ary) +rb_mod_shvar_at(mod, ary) VALUE mod, ary; { if (!FL_TEST(mod, FL_TAINT) && rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't get metainfo"); if (RCLASS(mod)->iv_tbl) { - st_foreach(RCLASS(mod)->iv_tbl, const_i, ary); + st_foreach(RCLASS(mod)->iv_tbl, sv_i, ary); } if ((VALUE)mod == rb_cObject) { - st_foreach(rb_class_tbl, const_i, ary); + st_foreach(rb_class_tbl, sv_i, ary); if (autoload_tbl) { st_foreach(autoload_tbl, autoload_i, ary); } @@ -1107,10 +1140,24 @@ rb_mod_const_at(mod, ary) } VALUE -rb_mod_constants(mod) - VALUE mod; +rb_mod_const_at(mod, ary) + VALUE mod, ary; { - return rb_mod_const_at(mod, rb_ary_new()); + return rb_mod_shvar_at(mod, ary); +} + +VALUE +rb_mod_shvar_of(mod, ary) + VALUE mod; + VALUE ary; +{ + rb_mod_shvar_at(mod, ary); + for (;;) { + mod = RCLASS(mod)->super; + if (!mod) break; + rb_mod_shvar_at(mod, ary); + } + return ary; } VALUE @@ -1118,17 +1165,25 @@ rb_mod_const_of(mod, ary) VALUE mod; VALUE ary; { - rb_mod_const_at(mod, ary); - for (;;) { - mod = RCLASS(mod)->super; - if (!mod) break; - rb_mod_const_at(mod, ary); - } - return ary; + return rb_mod_shvar_of(mod, ary); +} + +VALUE +rb_mod_shvars(mod) + VALUE mod; +{ + return rb_mod_shvar_of(mod, rb_ary_new()); +} + +VALUE +rb_mod_constants(mod) + VALUE mod; +{ + return rb_mod_shvars(mod); } int -rb_const_defined_at(klass, id) +rb_shvar_defined_at(klass, id) VALUE klass; ID id; { @@ -1136,11 +1191,19 @@ rb_const_defined_at(klass, id) return Qtrue; } if (klass == rb_cObject) { - return rb_const_defined(klass, id); + return rb_shvar_defined(klass, id); } return Qfalse; } +int +rb_const_defined_at(klass, id) + VALUE klass; + ID id; +{ + return rb_shvar_defined_at(klass, id); +} + int rb_autoload_defined(id) ID id; @@ -1151,7 +1214,7 @@ rb_autoload_defined(id) } int -rb_const_defined(klass, id) +rb_shvar_defined(klass, id) VALUE klass; ID id; { @@ -1164,15 +1227,23 @@ rb_const_defined(klass, id) tmp = RCLASS(tmp)->super; } if (BUILTIN_TYPE(klass) == T_MODULE) { - return rb_const_defined(rb_cObject, id); + return rb_shvar_defined(rb_cObject, id); } if (st_lookup(rb_class_tbl, id, 0)) return Qtrue; return rb_autoload_defined(id); } +int +rb_const_defined(klass, id) + VALUE klass; + ID id; +{ + return rb_shvar_defined(klass, id); +} + void -rb_const_set(klass, id, val) +rb_shvar_set(klass, id, val) VALUE klass; ID id; VALUE val; @@ -1182,13 +1253,61 @@ rb_const_set(klass, id, val) if (!RCLASS(klass)->iv_tbl) { RCLASS(klass)->iv_tbl = st_init_numtable(); } - else if (st_lookup(RCLASS(klass)->iv_tbl, id, 0)) { - rb_warn("already initialized constant %s", rb_id2name(id)); - } st_insert(RCLASS(klass)->iv_tbl, id, val); } +void +rb_const_set(klass, id, val) + VALUE klass; + ID id; + VALUE val; +{ + return rb_shvar_set(klass, id, val); +} + +void +rb_shvar_assign(klass, id, val) + VALUE klass; + ID id; + VALUE val; +{ + VALUE tmp = klass; + + while (tmp) { + if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,0)) { + st_insert(RCLASS(tmp)->iv_tbl, id, val); + return; + } + tmp = RCLASS(tmp)->super; + } + /* pre-defined class */ + if (st_lookup(rb_class_tbl, id, 0)) { + st_delete(rb_class_tbl, id, 0); + st_insert(RCLASS(rb_cObject)->iv_tbl, id, val); + return; + } + + /* autoload */ + if (autoload_tbl && st_lookup(autoload_tbl, id, 0)) { + char *modname; + + st_delete(autoload_tbl, &id, &modname); + free(modname); + st_insert(RCLASS(rb_cObject)->iv_tbl, id, val); + return; + } + + /* Uninitialized constant */ + if (klass && klass != rb_cObject) + rb_raise(rb_eNameError, "uninitialized constant %s::%s", + RSTRING(rb_class_path(klass))->ptr, + rb_id2name(id)); + else { + rb_raise(rb_eNameError, "uninitialized constant %s",rb_id2name(id)); + } +} + void rb_define_const(klass, name, val) VALUE klass; @@ -1200,10 +1319,19 @@ rb_define_const(klass, name, val) if (klass == rb_cObject) { rb_secure(4); } - if (!rb_is_const_id(id)) { - rb_raise(rb_eNameError, "wrong constant name %s", name); + if (!rb_is_shared_id(id)) { + rb_raise(rb_eNameError, "wrong shared variable name %s", name); } - rb_const_set(klass, id, val); + rb_shvar_set(klass, id, val); +} + +void +rb_define_shvar(klass, name, val) + VALUE klass; + const char *name; + VALUE val; +{ + return rb_define_const(klass, name, val); } void @@ -1214,6 +1342,14 @@ rb_define_global_const(name, val) rb_define_const(rb_cObject, name, val); } +void +rb_define_global_shvar(name, val) + const char *name; + VALUE val; +{ + rb_define_global_const(name, val); +} + VALUE rb_iv_get(obj, name) VALUE obj; diff --git a/version.h b/version.h index 032524219c..8439450925 100644 --- a/version.h +++ b/version.h @@ -1,4 +1,4 @@ #define RUBY_VERSION "1.5.0" -#define RUBY_RELEASE_DATE "1999-10-12" +#define RUBY_RELEASE_DATE "1999-11-17" #define RUBY_VERSION_CODE 150 -#define RUBY_RELEASE_CODE 19991012 +#define RUBY_RELEASE_CODE 19991117