Project

General

Profile

Bug #5828

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

Added by agrimm (Andrew Grimm) almost 8 years ago. Updated over 5 years ago.

Status:
Closed
Priority:
Normal
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

Associated revisions

Revision 4169440f
Added by akr (Akira Tanaka) over 5 years ago

  • 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]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46370 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 46370
Added by akr (Akira Tanaka) over 5 years ago

  • 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]

Revision 46370
Added by akr (Akira Tanaka) over 5 years ago

  • 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]

Revision 46370
Added by akr (Akira Tanaka) over 5 years ago

  • 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]

Revision 46370
Added by akr (Akira Tanaka) over 5 years ago

  • 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]

Revision 46370
Added by akr (Akira Tanaka) over 5 years ago

  • 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]

Revision 46370
Added by akr (Akira Tanaka) over 5 years ago

  • 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]

History

#1

Updated by ko1 (Koichi Sasada) over 7 years ago

  • Assignee set to akr (Akira Tanaka)

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

#2

Updated by shyouhei (Shyouhei Urabe) over 7 years ago

  • Status changed from Open to Assigned

Updated by akr (Akira Tanaka) over 5 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 5 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 5 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 5 years ago

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