Project

General

Profile

Actions

Bug #21330

open

Namespace: Class and Module frozen status is not namespaced

Added by byroot (Jean Boussier) 23 days ago. Updated 2 days ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:122042]

Description

File.write("/tmp/test.rb", <<~'RUBY')
  Hash.freeze
RUBY

ns = Namespace.new
ns.require("/tmp/test.rb")

class Hash
  def monkey_patch
  end
end

Expected behavior:

Since the monkey patch is in a different namespace, I'd expect it to not impact code that is running in another namespace.

Actual behavior:

test.rb:9:in '<class:Hash>': can't modify frozen class: Hash (FrozenError)

The class is frozen globally, breaking code in other namespaces.

Is this by design, or does that mean the frozen status need to be moved in the classext_t as well?

cc @tagomoris (Satoshi Tagomori)

Actions #1

Updated by byroot (Jean Boussier) 23 days ago

  • Subject changed from Namespace: Class and Module frozen status is not namespace to Namespace: Class and Module frozen status is not namespaced

Updated by tagomoris (Satoshi Tagomori) 23 days ago

The frozen flag is what I missed. I think we should move the flag to rb_classext_t.

Actions #3

Updated by hsbt (Hiroshi SHIBATA) 2 days ago

  • Tags set to namespace

Updated by ko1 (Koichi Sasada) 2 days ago

I'm afraid that moving frozen flag into class_ext (and each built-in class variants can has each frozen state) makese OBJ_FROZEN code:

// include/ruby/internal/fl_type.h
static inline VALUE
RB_OBJ_FROZEN_RAW(VALUE obj)
{
    return RB_FL_TEST_RAW(obj, RUBY_FL_FREEZE);
}

especially, if nobody freeze builtin classes. Any usecases?

Updated by jeremyevans0 (Jeremy Evans) 2 days ago

ko1 (Koichi Sasada) wrote in #note-4:

I'm afraid that moving frozen flag into class_ext (and each built-in class variants can has each frozen state) makese OBJ_FROZEN code:

// include/ruby/internal/fl_type.h
static inline VALUE
RB_OBJ_FROZEN_RAW(VALUE obj)
{
    return RB_FL_TEST_RAW(obj, RUBY_FL_FREEZE);
}

especially, if nobody freeze builtin classes. Any usecases?

roda-sequel-stack (https://github.com/jeremyevans/roda-sequel-stack) supports and recommends freezing all core classes at runtime (after the application is loaded). This is how production Roda applications are commonly run. Freezing core classes is recommended to ensure that no libraries the application is using are modifying the core classes at runtime (they probably aren't, but how can you be sure without freezing them)?

Updated by byroot (Jean Boussier) 2 days ago

I'm afraid that moving frozen flag into class_ext (and each built-in class variants can has each frozen state) makese OBJ_FROZEN code:

It seems like your sentence is missing a word. Did you mean to say that it will make OBJ_FROZEN slower? If so yes, absolutely, but I thought it was a given. Namespaces are introducing a level of indirection it need to be checked and isn't cheap.

But on this note I'm currently working on two patches that may help with that:

With those two changes, once finished, I believe I can come up with a RB_OBJ_FROZEN_RAW that has almost the exact same performance.

Any usecases?

What Jeremy said, but also just consistency? It's very hard to reason about a feature that isn't behaving consistently.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0