Project

General

Profile

Actions

Bug #5828

closed

Non anonymous classes can't be frozen, cloned and then inspected

Added by agrimm (Andrew Grimm) about 12 years ago. Updated almost 10 years ago.

Status:
Closed
Target version:
-
ruby -v:
ruby 2.0.0dev (2011-11-27 trunk 33860) [x86_64-darwin10.8.0]
Backport:
[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

Actions #1

Updated by ko1 (Koichi Sasada) about 12 years ago

  • Assignee set to akr (Akira Tanaka)

Tanaka-san says he found the reason of this issue.

Actions #2

Updated by shyouhei (Shyouhei Urabe) about 12 years ago

  • Status changed from Open to Assigned

Updated by akr (Akira Tanaka) almost 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) almost 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) almost 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) almost 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.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0