summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-11-17 07:30:37 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-11-17 07:30:37 +0000
commit8e48dc16e97a783a69f0972b4882ad2faae561ea (patch)
treec25927a4f286e4ed5f3c7637076332e99287b089
parent943e99e62746388456955729e9f8417f3df5f8b5 (diff)
19991117
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@564 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog39
-rw-r--r--ToDo8
-rw-r--r--class.c4
-rw-r--r--enum.c19
-rw-r--r--eval.c93
-rw-r--r--intern.h19
-rw-r--r--io.c1
-rw-r--r--lib/pstore.rb11
-rw-r--r--lib/singleton.rb1
-rw-r--r--node.h2
-rw-r--r--object.c28
-rw-r--r--parse.y43
-rw-r--r--re.c5
-rw-r--r--ruby.c4
-rw-r--r--ruby.h9
-rw-r--r--sample/rename.rb2
-rw-r--r--struct.c2
-rw-r--r--variable.c204
-rw-r--r--version.h4
19 files changed, 366 insertions, 132 deletions
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 <matz@netlab.co.jp>
+
+ * io.c (Init_IO): $defout (alias of $>) added.
+
+Tue Nov 16 09:47:14 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * lib/pstore.rb: add mutual lock using symlink.
+
+Mon Nov 15 16:50:34 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * 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 <JCA02266@nifty.ne.jp>
+
+ * re.c (rb_reg_source): should not call rb_reg_expr_str()
+ everytime.
+
+Sat Nov 13 07:34:18 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * 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 <eguchi@shizuokanet.ne.jp>
* 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;
@@ -4547,14 +4549,21 @@ rb_id2name(id)
}
int
-rb_is_const_id(id)
+rb_is_shared_id(id)
ID id;
{
- if (is_const_id(id)) return Qtrue;
+ if (is_shared_id(id)) return Qtrue;
return Qfalse;
}
int
+rb_is_const_id(id)
+ ID id;
+{
+ return rb_is_shared_id(id);
+}
+
+int
rb_is_instance_id(id)
ID id;
{
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;
{
@@ -641,6 +641,16 @@ rb_gvar_set2(name, 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,28 +1140,50 @@ 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_const_of(mod, ary)
+rb_mod_shvar_of(mod, ary)
VALUE mod;
VALUE ary;
{
- rb_mod_const_at(mod, ary);
+ rb_mod_shvar_at(mod, ary);
for (;;) {
mod = RCLASS(mod)->super;
if (!mod) break;
- rb_mod_const_at(mod, ary);
+ rb_mod_shvar_at(mod, ary);
}
return ary;
}
+VALUE
+rb_mod_const_of(mod, ary)
+ VALUE mod;
+ VALUE 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,12 +1191,20 @@ 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,14 +1253,62 @@ 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;
const char *name;
@@ -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