Moin,
At Tue, 15 Jun 2004 17:08:36 +0900,
Florian Gross wrote in [ruby-talk:103646]:
irb(main):034:0> File.open("C:/autoexec.bat").freeze.inspect
TypeError: can't modify frozen File # inspect doesn't modify
from (irb):34:in `inspect'
# This one also happens for File#path etc.
IO#inspect also fails in secure mode (when $SAFE >= 4). I'm
not sure whether it should be possible or not.
irb(main):063:0> Dir.new(".").freeze.send
initialize, "C:/").read
=> "katapult.zip" # Initialize executed despite Dir being frozen
This is simple to fix, adding rb_check_frozen() to every
initialize methods... but tiresome.
irb(main):097:0> Class.new.freeze.to_s
TypeError: can't modify frozen object # to_s doesn't modify
from (irb):97:in `to_s'
Seems wrong.
Index: variable.c
===================================================================
RCS file: /var/cvs/src/ruby/variable.c,v
retrieving revision 1.113
diff -u -2 -p -r1.113 variable.c
--- variable.c 14 May 2004 16:39:15 -0000 1.113
+++ variable.c 16 Jun 2004 13:35:57 -0000
@@ -23,4 +23,7 @@ st_table *rb_class_tbl;
static ID autoload, classpath, tmp_classpath;
+#define ENSURE_IV_TBL(tbl) \
+ ((tbl) ? (tbl) : ((tbl) = st_init_numtable(), (st_table *)0))
+
void
Init_var_tables()
@@ -131,7 +134,5 @@ find_class_path(klass)
}
if (arg.path) {
- if (!ROBJECT(klass)->iv_tbl) {
- ROBJECT(klass)->iv_tbl = st_init_numtable();
- }
+ ENSURE_IV_TBL(ROBJECT(klass)->iv_tbl);
st_insert(ROBJECT(klass)->iv_tbl, classpath, arg.path);
st_delete(RCLASS(klass)->iv_tbl, &tmp_classpath, 0);
@@ -209,5 +210,6 @@ rb_class_path(klass)
sprintf(RSTRING(path)->ptr, "#<%s:0x%lx>", s, klass);
RSTRING(path)->len = strlen(RSTRING(path)->ptr);
- rb_ivar_set(klass, tmp_classpath, path);
+ ENSURE_IV_TBL(ROBJECT(klass)->iv_tbl);
+ st_insert(ROBJECT(klass)->iv_tbl, tmp_classpath, path);
return path;
@@ -873,7 +875,5 @@ generic_ivar_set(obj, id, val)
special_generic_ivar = 1;
}
- if (!generic_iv_tbl) {
- generic_iv_tbl = st_init_numtable();
- }
+ ENSURE_IV_TBL(generic_iv_tbl);
if (!st_lookup(generic_iv_tbl, obj, (st_data_t *)&tbl)) {
@@ -1050,5 +1050,5 @@ rb_ivar_set(obj, id, val)
case T_CLASS:
case T_MODULE:
- if (!ROBJECT(obj)->iv_tbl) ROBJECT(obj)->iv_tbl = st_init_numtable();
+ ENSURE_IV_TBL(ROBJECT(obj)->iv_tbl);
st_insert(ROBJECT(obj)->iv_tbl, id, val);
break;
@@ -1510,7 +1510,5 @@ rb_mod_const_at(mod, data)
{
st_table *tbl = data;
- if (!tbl) {
- tbl = st_init_numtable();
- }
+ ENSURE_IV_TBL(tbl);
if (RCLASS(mod)->iv_tbl) {
st_foreach(RCLASS(mod)->iv_tbl, sv_i, (st_data_t)tbl);
@@ -1645,8 +1643,5 @@ mod_av_set(klass, id, val, isconst)
}
}
- if (!RCLASS(klass)->iv_tbl) {
- RCLASS(klass)->iv_tbl = st_init_numtable();
- }
- else if (isconst) {
+ if (ENSURE_IV_TBL(RCLASS(klass)->iv_tbl) && isconst) {
VALUE value = Qfalse;