mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			742 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			742 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| module SuperSpecs
 | |
|   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,
 | |
|     # Alias2's superclass is next.
 | |
|     #
 | |
|     # 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
 | |
|         block_ref = -> { 15 }
 | |
|         [super { 14 }, super(&block_ref)]
 | |
|       end
 | |
| 
 | |
|       def c
 | |
|         block_ref = -> { 16 }
 | |
|         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
 | |
| 
 | |
|   module ZSuperWithRestAndPost
 | |
|     class A
 | |
|       def m(*args, a, b)
 | |
|         args
 | |
|       end
 | |
| 
 | |
|       def m_modified(*args, a, b)
 | |
|         args
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     class B < A
 | |
|       def m(*args, a, b)
 | |
|         super
 | |
|       end
 | |
| 
 | |
|       def m_modified(*args, a, b)
 | |
|         args[1] = 14
 | |
|         super
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   module ZSuperWithRestOthersAndPost
 | |
|     class A
 | |
|       def m(a, *args, b)
 | |
|         args
 | |
|       end
 | |
| 
 | |
|       def m_modified(a, *args, b)
 | |
|         args
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     class B < A
 | |
|       def m(a, *args, b)
 | |
|         super
 | |
|       end
 | |
| 
 | |
|       def m_modified(a, *args, b)
 | |
|         args[1] = 14
 | |
|         super
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   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
 | |
| 
 | |
|   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
 | |
| 
 | |
|   module Keywords
 | |
|     class Arguments
 | |
|       def foo(**args)
 | |
|         args
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     # ----
 | |
| 
 | |
|     class RequiredArguments < Arguments
 | |
|       def foo(a:)
 | |
|         super
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     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
 | |
|     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
 | 
