Project

General

Profile

Actions

Bug #18292

closed

3.1.0-dev `include` cause Module to be marked as initialized

Added by byroot (Jean Boussier) 3 months ago. Updated 17 days ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 3.1.0dev (2021-11-08T09:35:22Z master 7cc4e147fc)
[ruby-core:105966]

Description

Some subtle change I found while testing our app compatibility with Ruby head:

class Mod1 < Module
  def initialize(...)
    super
  end
end
p Mod1.new

class Mod2 < Module
  def initialize(...)
    include Enumerable
    super
  end
end
p Mod2.new

On 3.0:

#<Mod1:0x00007fbf9b825b38>
#<Mod2:0x00007fbf9b825818>

On ruby-head:

#<Mod1:0x00000001108cb1d8>
/tmp/module.rb:11:in `initialize': already initialized module (TypeError)
    from /tmp/module.rb:11:in `initialize'

I suspect this might be a result of https://bugs.ruby-lang.org/issues/17048, but I have to admit I'm not certain so I'd rather report it.

Actions #1

Updated by byroot (Jean Boussier) 3 months ago

  • ruby -v set to ruby 3.1.0dev (2021-11-08T09:35:22Z master 7cc4e147fc)

Updated by jeremyevans0 (Jeremy Evans) 22 days ago

A simple work around for this is to include after calling super.

initialize checks whether the module is uninitialized, and fails otherwise. When calling include, the module is marked as initialized. If you call include before super, then the module is initialized before initialize is called, resulting in an error.

I'm not sure why this check in initialize is needed. initialize only does the equivalent of module_exec if a block is passed. I think it's possible to rearrange the code to fix this. I submitted a pull request for this change: https://github.com/ruby/ruby/pull/5398

Actions #3

Updated by jeremyevans (Jeremy Evans) 21 days ago

  • Status changed from Open to Closed

Applied in changeset git|a79c59472df38297c246b27713c277f2edaefa7a.


Allow include before calling Module#initialize

This is to allow Module subclasses that include modules before
calling super in the subclass's initialize.

Remove rb_module_check_initializable from Module#initialize.
Module#initialize only calls module_exec if a block is passed,
it doesn't have other issues that would cause problems if
called multiple times or with an already initialized module.

Move initialization of super to Module#allocate, though I'm not
sure it is required there. However, it's needed to be removed
from Module#initialize for this to work.

Fixes [Bug #18292]

Updated by byroot (Jean Boussier) 17 days ago

@jeremyevans thanks for the fix. Do you think we should mark this as a 3.1 backport?

Updated by jeremyevans0 (Jeremy Evans) 17 days ago

  • Backport changed from 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN to 2.6: DONTNEED, 2.7: DONTNEED, 3.0: DONTNEED, 3.1: REQUIRED

byroot (Jean Boussier) wrote in #note-4:

@jeremyevans thanks for the fix. Do you think we should mark this as a 3.1 backport?

Sure, that makes sense to me.

Actions

Also available in: Atom PDF