Bug #5828
closed
Non anonymous classes can't be frozen, cloned and then inspected
Added by agrimm (Andrew Grimm) almost 13 years ago.
Updated over 10 years ago.
ruby -v:
ruby 2.0.0dev (2011-11-27 trunk 33860) [x86_64-darwin10.8.0]
[ruby-core:41858]
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
- Assignee set to akr (Akira Tanaka)
Tanaka-san says he found the reason of this issue.
- Status changed from Open to Assigned
- 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.
I'm happy for this bug to be closed, as I don't have a need to freeze and clone a class.
- 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]
I decided to fix this problem because to_s method is useful for debugging and exception on to_s can be
irritating.
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0Like0