Bug #5828
closedNon anonymous classes can't be frozen, cloned and then inspected
Description
=begin
If you assign a class to a constant (that is, it isn't anonymous), and you freeze it and then clone it, you can't call to_s on it.
MyClass = Class.new ; MyClass.freeze.clone.to_s
RuntimeError: can't modify frozen Class
from (irb):1:in `to_s'
from (irb):1
from /Users/agrimm/.rvm/rubies/ruby-head/bin/irb:16:in `<main>'
MyConstantObject = Object.new ; MyConstantObject.freeze.clone.to_s # => "#<Object:0x00000100884d60>"
MyClass_2 = Class.new ; MyClass_2.clone.to_s # => "#<Class:0x00000100872930>"
MyClass_3 = Class.new ; MyClass_3.freeze.to_s # => "MyClass_3"
MyClass_4 = Class.new.freeze ; MyClass_4.clone.to_s # => "#<Class:0x0000010088d4d8>"
MyClass_5 = Class.new.freeze ; MyClass_5.freeze.clone.to_s # => An exception
local_variable_class = Class.new ; local_variable_class.freeze.clone.to_s # => "#<Class:0x00000100964028>"
Presumably this is caused by class only determining whether it's assigned to a constant when it's first inspected.
I don't have a use case for freezing and cloning a class.
=end
Updated by ko1 (Koichi Sasada) almost 13 years ago
- Assignee set to akr (Akira Tanaka)
Tanaka-san says he found the reason of this issue.
Updated by shyouhei (Shyouhei Urabe) almost 13 years ago
- Status changed from Open to Assigned
Updated by akr (Akira Tanaka) over 10 years ago
- Status changed from Assigned to Feedback
The name of anonymous class is searched and cached when it is first inspected.
The cache is implemented as a hidden instance variable of the class.
If the class is frozen, the cache is failed as the exception because the instance variable is not assignable.
Note that Class.new.freeze.to_s doesn't raise the exception.
This is because Kernel#freeze is redefined by Module#freeze and it caches the class name before freezing.
Kernel#clone is not redefined.
So there is not such trick to avoid the exception.
I'm not sure that it is worth to fix this problem.
Updated by agrimm (Andrew Grimm) over 10 years ago
I'm happy for this bug to be closed, as I don't have a need to freeze and clone a class.
Updated by akr (Akira Tanaka) over 10 years ago
- Status changed from Feedback to Closed
- % Done changed from 0 to 100
Applied in changeset r46370.
- object.c (rb_mod_initialize_clone): Override Kernel#initialize_clone
to avoid an exception on Class.new.freeze.clone.to_s.
Reported by Andrew Grimm. [ruby-core:41858] [Bug #5828]
Updated by akr (Akira Tanaka) over 10 years ago
I decided to fix this problem because to_s method is useful for debugging and exception on to_s can be
irritating.