Project

General

Profile

Actions

Bug #16977

closed

Ambiguous lookup super for refinements

Bug #16977: Ambiguous lookup super for refinements

Added by ssnickolay (Nikolay Sverchkov) over 5 years ago. Updated over 5 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.6.3p62 (2019-04-16 revision 67580)
[ruby-core:98917]

Description

In specification we have the note

Note that super in a method of a refinement invokes the method in the refined class even if there is another refinement which has been activated in the same context.

If we take a look at the example:

module A
  def foo
    "foo from A"
  end
end

class C
  def foo
    "foo from C"
  end
end

refinement =
  Module.new do
    refine C do
      include A
    end
  end

refinement2 =
  Module.new do
    refine C do
      def foo
        super
      end
    end
  end

using refinement
using refinement2

puts C.new.foo

# => "foo from C"

This works as described in the specification.

However, if we replace refinement2 in the example with


# the same A, C and refinement definitions here

module B
  def foo
    super
  end
end

refinement2 =
  Module.new do
    refine C do
      include B
    end
  end

using refinement
using refinement2

puts C.new.foo

# => "foo from A"

I don’t understand why include works differently than refining a method directly.
From my point of view, we should get foo from C in both cases.


Related issues 1 (0 open1 closed)

Related to Ruby - Bug #17007: SystemStackError when using super inside Module included and lexically inside refinementClosedshugo (Shugo Maeda)Actions

Updated by shugo (Shugo Maeda) over 5 years ago Actions #1 [ruby-core:98934]

ssnickolay (Nikolay Sverchkov) wrote:

In specification we have the note

Note that super in a method of a refinement invokes the method in the refined class even if there is another refinement which has been activated in the same context.

If we take a look at the example:
(snip)
I don’t understand why include works differently than refining a method directly.
From my point of view, we should get foo from C in both cases.

In the former case, super is called in the scope where a refinement is defined, and thus it invokes the method in the refined class.
However, in the latter case, super is called outside the scope where a refinement is defined, and it looks up the ancestor chain.

The behavior of include in refine blocks is confusing, so it may be prohibited in the future.

Updated by Eregon (Benoit Daloze) over 5 years ago Actions #2

  • Related to Bug #17007: SystemStackError when using super inside Module included and lexically inside refinement added

Updated by jeremyevans (Jeremy Evans) over 5 years ago Actions #3

  • Status changed from Open to Closed

Applied in changeset git|021cec938af55a7ef368eadc99a6e3ff2252510e.


Clarify behavior of super in method in module included in refinement [ci skip]

Fixes [Bug #16977]

Actions

Also available in: PDF Atom