Project

General

Profile

Actions

Bug #14744

closed

Refinements modules have a superclass

Added by Eregon (Benoit Daloze) over 3 years ago. Updated 2 months ago.

Status:
Closed
Priority:
Normal
Target version:
-
ruby -v:
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
[ruby-core:86949]
Tags:

Description

$ ruby -e 'module M; refine Array do; p self; p self.class; p ancestors; end; end'
#<refinement:Array@M>
Module
[#<refinement:Array@M>, Array, Enumerable, Object, Kernel, BasicObject]

So the refinement module (self in the refine Array do block) is a Module, but looking at its ancestors it has Array as a "superclass".

Is that expected?
I thought modules can never have a superclass in Ruby.

Updated by shevegen (Robert A. Heiler) over 3 years ago

I thought modules can never have a superclass in Ruby.

This may be a bug, I think; other modules do not seem to have
anything but themselves if you call .ancestors() on them either.

I am not absolutely certain, but perhaps either way it could be
mentioned in the documentation too, whether modules (including
refinements) can lead to modules having superclasses.

Updated by shugo (Shugo Maeda) over 3 years ago

  • Assignee set to matz (Yukihiro Matsumoto)

So the refinement module (self in the refine Array do block) is a Module, but looking at its ancestors it has Array as a "superclass".

Is that expected?

The superclass of a refinement module is for implementing super in refined methods.
However, it may be better to hidden from reflection APIs.

What do you think, Matz?

Updated by Eregon (Benoit Daloze) over 3 years ago

shugo (Shugo Maeda) wrote:

The superclass of a refinement module is for implementing super in refined methods.
However, it may be better to hidden from reflection APIs.

I see, thank you for the explanation.

I'm not sure it's good to hide though, as I noticed this interesting case by seeing code like:

module R
  refine Array do
    p instance_method(:sum)
  end
end

I think either super should be implemented differently to not rely on setting a Module's superclass,
or we leave it as it is, and have it visible with reflection APIs since anyway it behaves like there is a "superclass".

FWIW currently in TruffleRuby we do a slightly different lookup when looking for the super method of a refined method, and look at the active refinements to find the super method,
and then use an inline cache to avoid repeated lookups.

Actions #4

Updated by hsbt (Hiroshi SHIBATA) almost 2 years ago

  • Tags set to refine

Updated by matz (Yukihiro Matsumoto) 2 months ago

I am so sorry for being late.
I agree with shugo (Shugo Maeda)'s opinion in #note-2. We should hide Array in the example.

Matz.

Updated by shugo (Shugo Maeda) 2 months ago

  • Assignee changed from matz (Yukihiro Matsumoto) to shugo (Shugo Maeda)
  • Status changed from Open to Assigned

Updated by Eregon (Benoit Daloze) 2 months ago

matz (Yukihiro Matsumoto) Should instance_method and other methods magically find the method on the refined class, even though self is a Module though, like in https://bugs.ruby-lang.org/issues/14744#note-3 ?

Actions #8

Updated by shugo (Shugo Maeda) 2 months ago

  • Status changed from Assigned to Closed

Applied in changeset git|754adbee91c2d4a4e84e9271724ca33f630d1916.


Module#ancestors should not return superclasses of refinements

[ruby-core:86949] [Bug #14744]

Reported by Eregon (Benoit Daloze). Thanks!

Actions

Also available in: Atom PDF