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;
-- Nobu Nakada