2019-02-21 10:38:59 -05:00
|
|
|
module SuperSpecs
|
2017-05-07 08:04:49 -04:00
|
|
|
module S1
|
|
|
|
class A
|
|
|
|
def foo(a)
|
|
|
|
a << "A#foo"
|
|
|
|
bar(a)
|
|
|
|
end
|
|
|
|
def bar(a)
|
|
|
|
a << "A#bar"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class B < A
|
|
|
|
def foo(a)
|
|
|
|
a << "B#foo"
|
|
|
|
super(a)
|
|
|
|
end
|
|
|
|
def bar(a)
|
|
|
|
a << "B#bar"
|
|
|
|
super(a)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module S2
|
|
|
|
class A
|
|
|
|
def baz(a)
|
|
|
|
a << "A#baz"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class B < A
|
|
|
|
def foo(a)
|
|
|
|
a << "B#foo"
|
|
|
|
baz(a)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class C < B
|
|
|
|
def baz(a)
|
|
|
|
a << "C#baz"
|
|
|
|
super(a)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module S3
|
|
|
|
class A
|
|
|
|
def foo(a)
|
|
|
|
a << "A#foo"
|
|
|
|
end
|
|
|
|
def self.foo(a)
|
|
|
|
a << "A.foo"
|
|
|
|
end
|
|
|
|
def self.bar(a)
|
|
|
|
a << "A.bar"
|
|
|
|
foo(a)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class B < A
|
|
|
|
def self.foo(a)
|
|
|
|
a << "B.foo"
|
|
|
|
super(a)
|
|
|
|
end
|
|
|
|
def self.bar(a)
|
|
|
|
a << "B.bar"
|
|
|
|
super(a)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module S4
|
|
|
|
class A
|
|
|
|
def foo(a)
|
|
|
|
a << "A#foo"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class B < A
|
|
|
|
def foo(a, b)
|
|
|
|
a << "B#foo(a,#{b})"
|
|
|
|
super(a)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class S5
|
|
|
|
def here
|
|
|
|
:good
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class S6 < S5
|
|
|
|
def under
|
|
|
|
yield
|
|
|
|
end
|
|
|
|
|
|
|
|
def here
|
|
|
|
under {
|
|
|
|
super
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class S7 < S5
|
|
|
|
define_method(:here) { super() }
|
|
|
|
end
|
|
|
|
|
|
|
|
module MS1
|
|
|
|
module ModA
|
|
|
|
def foo(a)
|
|
|
|
a << "ModA#foo"
|
|
|
|
bar(a)
|
|
|
|
end
|
|
|
|
def bar(a)
|
|
|
|
a << "ModA#bar"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class A
|
|
|
|
include ModA
|
|
|
|
end
|
|
|
|
module ModB
|
|
|
|
def bar(a)
|
|
|
|
a << "ModB#bar"
|
|
|
|
super(a)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class B < A
|
|
|
|
def foo(a)
|
|
|
|
a << "B#foo"
|
|
|
|
super(a)
|
|
|
|
end
|
|
|
|
include ModB
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module MS2
|
|
|
|
class A
|
|
|
|
def baz(a)
|
|
|
|
a << "A#baz"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
module ModB
|
|
|
|
def foo(a)
|
|
|
|
a << "ModB#foo"
|
|
|
|
baz(a)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class B < A
|
|
|
|
include ModB
|
|
|
|
end
|
|
|
|
class C < B
|
|
|
|
def baz(a)
|
|
|
|
a << "C#baz"
|
|
|
|
super(a)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module MultiSuperTargets
|
|
|
|
module M
|
|
|
|
def foo
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class BaseA
|
|
|
|
def foo
|
|
|
|
:BaseA
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class BaseB
|
|
|
|
def foo
|
|
|
|
:BaseB
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class A < BaseA
|
|
|
|
include M
|
|
|
|
end
|
|
|
|
|
|
|
|
class B < BaseB
|
|
|
|
include M
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module MS3
|
|
|
|
module ModA
|
|
|
|
def foo(a)
|
|
|
|
a << "ModA#foo"
|
|
|
|
end
|
|
|
|
def bar(a)
|
|
|
|
a << "ModA#bar"
|
|
|
|
foo(a)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class A
|
|
|
|
def foo(a)
|
|
|
|
a << "A#foo"
|
|
|
|
end
|
|
|
|
class << self
|
|
|
|
include ModA
|
|
|
|
end
|
|
|
|
end
|
|
|
|
class B < A
|
|
|
|
def self.foo(a)
|
|
|
|
a << "B.foo"
|
|
|
|
super(a)
|
|
|
|
end
|
|
|
|
def self.bar(a)
|
|
|
|
a << "B.bar"
|
|
|
|
super(a)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module MS4
|
|
|
|
module Layer1
|
|
|
|
def example
|
|
|
|
5
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module Layer2
|
|
|
|
include Layer1
|
|
|
|
def example
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class A
|
|
|
|
include Layer2
|
|
|
|
public :example
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class MM_A
|
|
|
|
undef_method :is_a?
|
|
|
|
end
|
|
|
|
|
|
|
|
class MM_B < MM_A
|
|
|
|
def is_a?(blah)
|
|
|
|
# should fire the method_missing below
|
|
|
|
super
|
|
|
|
end
|
|
|
|
|
|
|
|
def method_missing(*)
|
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Alias1
|
|
|
|
def name
|
|
|
|
[:alias1]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Alias2 < Alias1
|
|
|
|
def initialize
|
|
|
|
@times = 0
|
|
|
|
end
|
|
|
|
|
|
|
|
def name
|
|
|
|
if @times >= 10
|
|
|
|
raise "runaway super"
|
|
|
|
end
|
|
|
|
|
|
|
|
@times += 1
|
|
|
|
|
|
|
|
# Use this so that we can see collect all supers that we see.
|
|
|
|
# One bug that arises is that we call Alias2#name from Alias2#name
|
|
|
|
# as it's superclass. In that case, either we get a runaway recursion
|
|
|
|
# super OR we get the return value being [:alias2, :alias2, :alias1]
|
|
|
|
# rather than [:alias2, :alias1].
|
|
|
|
#
|
|
|
|
# Which one depends on caches and how super is implemented.
|
|
|
|
[:alias2] + super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Alias3 < Alias2
|
|
|
|
alias_method :name3, :name
|
|
|
|
# In the method table for Alias3 now should be a special alias entry
|
|
|
|
# that references Alias2 and Alias2#name (probably as an object).
|
|
|
|
#
|
|
|
|
# When name3 is called then, Alias2 (NOT Alias3) is presented as the
|
|
|
|
# current module to Alias2#name, so that when super is called,
|
2019-07-27 06:40:09 -04:00
|
|
|
# Alias2's superclass is next.
|
2017-05-07 08:04:49 -04:00
|
|
|
#
|
|
|
|
# Otherwise, Alias2 is next, which is where name was to begin with,
|
|
|
|
# causing the wrong #name method to be called.
|
|
|
|
end
|
|
|
|
|
|
|
|
module AliasWithSuper
|
|
|
|
module AS1
|
|
|
|
def foo
|
|
|
|
:a
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module BS1
|
|
|
|
def foo
|
|
|
|
[:b, super]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Base
|
|
|
|
extend AS1
|
|
|
|
extend BS1
|
|
|
|
end
|
|
|
|
|
|
|
|
class Trigger < Base
|
|
|
|
class << self
|
|
|
|
def foo_quux
|
|
|
|
foo_baz
|
|
|
|
end
|
|
|
|
|
|
|
|
alias_method :foo_baz, :foo
|
|
|
|
alias_method :foo, :foo_quux
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module RestArgsWithSuper
|
|
|
|
class A
|
|
|
|
def a(*args)
|
|
|
|
args
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class B < A
|
|
|
|
def a(*args)
|
|
|
|
args << "foo"
|
|
|
|
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class AnonymousModuleIncludedTwiceBase
|
|
|
|
def self.whatever
|
|
|
|
mod = Module.new do
|
|
|
|
def a(array)
|
|
|
|
array << "anon"
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
include mod
|
|
|
|
end
|
|
|
|
|
|
|
|
def a(array)
|
|
|
|
array << "non-anon"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class AnonymousModuleIncludedTwice < AnonymousModuleIncludedTwiceBase
|
|
|
|
whatever
|
|
|
|
whatever
|
|
|
|
end
|
|
|
|
|
|
|
|
module ZSuperWithBlock
|
|
|
|
class A
|
|
|
|
def a
|
|
|
|
yield
|
|
|
|
end
|
|
|
|
|
|
|
|
def b(&block)
|
|
|
|
block.call
|
|
|
|
end
|
|
|
|
|
|
|
|
def c
|
|
|
|
yield
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class B < A
|
|
|
|
def a
|
|
|
|
super { 14 }
|
|
|
|
end
|
|
|
|
|
|
|
|
def b
|
2019-07-27 06:40:09 -04:00
|
|
|
block_ref = -> { 15 }
|
2017-05-07 08:04:49 -04:00
|
|
|
[super { 14 }, super(&block_ref)]
|
|
|
|
end
|
|
|
|
|
|
|
|
def c
|
2019-07-27 06:40:09 -04:00
|
|
|
block_ref = -> { 16 }
|
2017-05-07 08:04:49 -04:00
|
|
|
super(&block_ref)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module ZSuperWithOptional
|
|
|
|
class A
|
|
|
|
def m(x, y, z)
|
|
|
|
z
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class B < A
|
|
|
|
def m(x, y, z = 14)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class C < A
|
|
|
|
def m(x, y, z = 14)
|
|
|
|
z = 100
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module ZSuperWithRest
|
|
|
|
class A
|
|
|
|
def m(*args)
|
|
|
|
args
|
|
|
|
end
|
|
|
|
|
|
|
|
def m_modified(*args)
|
|
|
|
args
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class B < A
|
|
|
|
def m(*args)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
|
|
|
|
def m_modified(*args)
|
|
|
|
args[1] = 14
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module ZSuperWithRestAndOthers
|
|
|
|
class A
|
|
|
|
def m(a, b, *args)
|
|
|
|
args
|
|
|
|
end
|
|
|
|
|
|
|
|
def m_modified(a, b, *args)
|
|
|
|
args
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class B < A
|
|
|
|
def m(a, b, *args)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
|
|
|
|
def m_modified(a, b, *args)
|
|
|
|
args[1] = 14
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-04-28 15:50:06 -04:00
|
|
|
module ZSuperWithRestReassigned
|
|
|
|
class A
|
|
|
|
def a(*args)
|
|
|
|
args
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class B < A
|
|
|
|
def a(*args)
|
|
|
|
args = ["foo"]
|
|
|
|
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module ZSuperWithRestReassignedWithScalar
|
|
|
|
class A
|
|
|
|
def a(*args)
|
|
|
|
args
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class B < A
|
|
|
|
def a(*args)
|
|
|
|
args = "foo"
|
|
|
|
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-05-07 08:04:49 -04:00
|
|
|
module ZSuperWithUnderscores
|
|
|
|
class A
|
|
|
|
def m(*args)
|
|
|
|
args
|
|
|
|
end
|
|
|
|
|
|
|
|
def m_modified(*args)
|
|
|
|
args
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class B < A
|
|
|
|
def m(_, _)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
|
|
|
|
def m_modified(_, _)
|
|
|
|
_ = 14
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-05-07 08:05:36 -04:00
|
|
|
|
2017-10-28 11:15:48 -04:00
|
|
|
module Keywords
|
|
|
|
class Arguments
|
2017-05-07 08:04:49 -04:00
|
|
|
def foo(**args)
|
|
|
|
args
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-10-28 11:15:48 -04:00
|
|
|
# ----
|
|
|
|
|
|
|
|
class RequiredArguments < Arguments
|
|
|
|
def foo(a:)
|
2017-05-07 08:04:49 -04:00
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-10-28 11:15:48 -04:00
|
|
|
class OptionalArguments < Arguments
|
|
|
|
def foo(b: 'b')
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class PlaceholderArguments < Arguments
|
|
|
|
def foo(**args)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# ----
|
|
|
|
|
|
|
|
class RequiredAndOptionalArguments < Arguments
|
|
|
|
def foo(a:, b: 'b')
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class RequiredAndPlaceholderArguments < Arguments
|
|
|
|
def foo(a:, **args)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class OptionalAndPlaceholderArguments < Arguments
|
|
|
|
def foo(b: 'b', **args)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# ----
|
|
|
|
|
|
|
|
class RequiredAndOptionalAndPlaceholderArguments < Arguments
|
|
|
|
def foo(a:, b: 'b', **args)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module RegularAndKeywords
|
|
|
|
class Arguments
|
|
|
|
def foo(a, **options)
|
|
|
|
[a, options]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# -----
|
|
|
|
|
|
|
|
class RequiredArguments < Arguments
|
|
|
|
def foo(a, b:)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class OptionalArguments < Arguments
|
|
|
|
def foo(a, c: 'c')
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class PlaceholderArguments < Arguments
|
|
|
|
def foo(a, **options)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# -----
|
|
|
|
|
|
|
|
class RequiredAndOptionalArguments < Arguments
|
|
|
|
def foo(a, b:, c: 'c')
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class RequiredAndPlaceholderArguments < Arguments
|
|
|
|
def foo(a, b:, **options)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class OptionalAndPlaceholderArguments < Arguments
|
|
|
|
def foo(a, c: 'c', **options)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# -----
|
|
|
|
|
|
|
|
class RequiredAndOptionalAndPlaceholderArguments < Arguments
|
|
|
|
def foo(a, b:, c: 'c', **options)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module SplatAndKeywords
|
|
|
|
class Arguments
|
|
|
|
def foo(*args, **options)
|
|
|
|
[args, options]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class AllArguments < Arguments
|
|
|
|
def foo(*args, **options)
|
|
|
|
super
|
|
|
|
end
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module FromBasicObject
|
|
|
|
def __send__(name, *args, &block)
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module IntermediateBasic
|
|
|
|
include FromBasicObject
|
|
|
|
end
|
|
|
|
|
|
|
|
class IncludesFromBasic
|
|
|
|
include FromBasicObject
|
|
|
|
|
|
|
|
def foobar; 43; end
|
|
|
|
end
|
|
|
|
|
|
|
|
class IncludesIntermediate
|
|
|
|
include IntermediateBasic
|
|
|
|
|
|
|
|
def foobar; 42; end
|
|
|
|
end
|
|
|
|
|
|
|
|
module SingletonCase
|
|
|
|
class Base
|
|
|
|
def foobar(array)
|
|
|
|
array << :base
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Foo < Base
|
|
|
|
def foobar(array)
|
|
|
|
array << :foo
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module SingletonAliasCase
|
|
|
|
class Base
|
|
|
|
def foobar(array)
|
|
|
|
array << :base
|
|
|
|
end
|
|
|
|
|
|
|
|
def alias_on_singleton
|
|
|
|
object = self
|
|
|
|
singleton = (class << object; self; end)
|
|
|
|
singleton.__send__(:alias_method, :new_foobar, :foobar)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Foo < Base
|
|
|
|
def foobar(array)
|
|
|
|
array << :foo
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|