Bug #1747
closedImmediate Values Can be Frozen
Description
=begin
On 1.8 you couldn't freeze an immediate. On 1.9 you can. Presumably this is a bug.
$ ruby -ve 'a=true;a.freeze;p a.frozen?'
ruby 1.9.2dev (2009-07-08 trunk 23995) [i686-linux]
true
$ ruby8 -ve 'a=true;a.freeze;p a.frozen?'
ruby 1.8.8dev (2009-07-01) [i686-linux]
false
=end
Updated by mame (Yusuke Endoh) over 15 years ago
=begin
Hi,
2009/7/9 Run Paint Run Run redmine@ruby-lang.org:
Bug #1747: Immediate Values Can be Frozen
http://redmine.ruby-lang.org/issues/show/1747Author: Run Paint Run Run
Status: Open, Priority: Normal
Category: core
ruby -v: ruby 1.9.2dev (2009-07-08 trunk 23995) [i686-linux]On 1.8 you couldn't freeze an immediate. On 1.9 you can. Presumably this is a bug.
$ ruby -ve 'a=true;a.freeze;p a.frozen?'
ruby 1.9.2dev (2009-07-08 trunk 23995) [i686-linux]
true$ ruby8 -ve 'a=true;a.freeze;p a.frozen?'
ruby 1.8.8dev (2009-07-01) [i686-linux]
false
It seems to be an intentional change for the following use case:
http://nov.tdiary.net/20071215.html#p02 (In Japanese)
CONST2 = ["hoge", 1].freeze
CONST2.each(&:freeze).all?(&:frozen?) #=> false (expected true)
I have no idea whether the the rationale is sensible or not.
If the compatibility can be ignored, it would be more reasonable that
all immediate values are frozen as a default.
--
Yusuke ENDOH mame@tsg.ne.jp
=end
Updated by mame (Yusuke Endoh) over 15 years ago
=begin
2009/7/10 Gary Wright gwtmp01@mac.com:
On Jul 9, 2009, at 12:15 AM, Yusuke ENDOH wrote:
It seems to be an intentional change for the following use case:
# http://nov.tdiary.net/20071215.html#p02 (In Japanese)
CONST2 = ["hoge", 1].freeze
CONST2.each(&:freeze).all?(&:frozen?) #=> false (expected true)I have no idea whether the the rationale is sensible or not.
If the compatibility can be ignored, it would be more reasonable that
all immediate values are frozen as a default.Making Fixnum instances frozen by default would break code that depended on
instance variable state:class Fixnum
attr_accessor :note
end42.note = 'the meaning of life'
I see. Then, the current behavior of 1.9 seems to me to be reasonable.
--
Yusuke ENDOH mame@tsg.ne.jp
=end
Updated by runpaint (Run Paint Run Run) over 15 years ago
=begin
Defining instance methods on Fixnum instances seems a particularly contrived case, even for ruby-core. ;-) The troubled soul wishing to engage in such hackery could surely stretch as far as using a Struct to wrap his annotated numerals? Note that freezing immediates does not imply freezing their classes; singleton methods could still be added if desired.
In addition, it makes little conceptual sense to freeze a value that is frozen by definition. This is especially obvious when you consider that because immediates can't be dup'd, they can never be thawed. The abstraction is broken.
Triskadekaphobiacs are presumably upset that, although 13.untrust appears to succeed and reinforce their beliefs, the state doesn't stick; 13.untrusted? subsequently returns false. Similarly, logicians and cynics alike must, respectively, rejoice and despair that true.untrust.untrusted?
is perpetually false.
It is irrational in equal measures to #freeze an immediate as it is to #dup it; to #taint truth (true
) as it is to assign to it; to #trust the unknowable (nil) as it is to #untrust it.
If methods don't make a sense for an object, they shouldn't appear to work. :-)
=end
Updated by mame (Yusuke Endoh) over 15 years ago
=begin
Hi,
2009/7/11 Run Paint Run Run redmine@ruby-lang.org:
Defining instance methods on Fixnum instances seems a particularly contrived case, even for ruby-core. ;-)
Please don't count on me so much ;-)
Triskadekaphobiacs are presumably upset that, although 13.untrust appears to succeed and reinforce their beliefs, the state doesn't stick; 13.untrusted? subsequently returns false. Similarly, logicians and cynics alike must, respectively, rejoice and despair that
true.untrust.untrusted?
is perpetually false.
Whoa! The current behavior of 1.9 is never reasonable.
Here is a patch:
Index: object.c¶
--- object.c (revision 24034)
+++ object.c (working copy)
@@ -641,6 +641,8 @@
return Qnil;
}
+static st_table immediate_tainted_tbl = 0;
+
/
- call-seq:
-
obj.tainted? => true or false
@@ -653,6 +655,10 @@
{
if (OBJ_TAINTED(obj))
return Qtrue;
- if (SPECIAL_CONST_P(obj)) {
- if (!immediate_tainted_tbl) return Qfalse;
- if (st_lookup(immediate_tainted_tbl, obj, 0)) return Qtrue;
- }
return Qfalse;
}
@@ -674,6 +680,12 @@
rb_error_frozen("object");
}
OBJ_TAINT(obj);
- if (SPECIAL_CONST_P(obj)) {
-
if (!immediate_tainted_tbl) {
-
immediate_tainted_tbl = st_init_numtable();
-
}
-
st_insert(immediate_tainted_tbl, obj, (st_data_t)Qtrue);
- }
}
return obj;
}
@@ -696,9 +708,14 @@
}
FL_UNSET(obj, FL_TAINT);
} - if (SPECIAL_CONST_P(obj) && immediate_tainted_tbl) {
- st_delete(immediate_tainted_tbl, &obj, NULL);
- }
return obj;
}
+static st_table immediate_untrusted_tbl = 0;
+
/
- call-seq:
-
obj.untrusted? => true or false
@@ -711,6 +728,10 @@
{
if (OBJ_UNTRUSTED(obj))
return Qtrue;
- if (SPECIAL_CONST_P(obj)) {
- if (!immediate_untrusted_tbl) return Qfalse;
- if (st_lookup(immediate_untrusted_tbl, obj, 0)) return Qtrue;
- }
return Qfalse;
}
@@ -730,6 +751,12 @@
rb_error_frozen("object");
}
OBJ_UNTRUST(obj);
- if (SPECIAL_CONST_P(obj)) {
-
if (!immediate_untrusted_tbl) {
-
immediate_untrusted_tbl = st_init_numtable();
-
}
-
st_insert(immediate_untrusted_tbl, obj, (st_data_t)Qtrue);
- }
}
return obj;
}
@@ -752,6 +779,9 @@
}
FL_UNSET(obj, FL_UNTRUSTED);
} - if (SPECIAL_CONST_P(obj) && immediate_untrusted_tbl) {
- st_delete(immediate_untrusted_tbl, &obj, NULL);
- }
return obj;
}
Maybe it is best to freeze all immediates (+ bignum) by default.
If Gary's example is needed at any cost, it can probably be rewrited
without using instance variables.
class Fixnum
h = {}
define_method(:note=) {|x| h[self] = x }
define_method(:note) { h[self] }
end
42.note = "the answer"
p 42.note
At any rate, I think that this is a talk about the future, perhaps
after Ruby 2.0.
--
Yusuke ENDOH mame@tsg.ne.jp
=end
Updated by runpaint (Run Paint Run Run) over 15 years ago
=begin
Triskadekaphobiacs are presumably upset that, although 13.untrust appears to succeed and reinforce their beliefs, the state doesn't stick; 13.untrusted? subsequently returns false. Similarly, logicians and cynics alike must, respectively, rejoice and despair that
true.untrust.untrusted?
is perpetually false.Whoa! The current behavior of 1.9 is never reasonable.
Here is a patch:
Thank you, Yusuke. :-) While I would prefer that immediates couldn't
be tainted/untrusted, I accept that's a topic for the future. For now,
that patch would certainly restore some sanity. :-)
=end
Updated by nobu (Nobuyoshi Nakada) over 15 years ago
- Assignee set to matz (Yukihiro Matsumoto)
=begin
=end
Updated by ujihisa (Tatsuhiro Ujihisa) almost 15 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
This issue seems to be closed already except that the topic for the future if immediates couldn't be tainted/untrusted.
=end