methods/super_forms.rb

tests/_examples/methods/super_forms.rb in the metorex repository.

# What `super` reaches and what it hands on: a bare `super` passes the
# parameters as they stand, a block reaches the method it was written in, an
# alias starts past the class that wrote the body, and a method nothing above
# defines goes to method_missing.

class Recorder
  def record(*values, **options)
    [values, options]
  end

  def pair(first, second)
    [first, second]
  end
end

class Adjusted < Recorder
  def record(first, second = 2, *rest, last, flag: :off)
    first = 10
    rest << :added
    super
  end

  def pair(_, _)
    _ = :changed
    super
  end
end
p(Adjusted.new.record(1, 5))
p(Adjusted.new.record(1, 3, 4, 5, flag: :on))
p(Adjusted.new.pair(:a, :b))

class InBlock < Recorder
  def record(value)
    [1].map { super() }.first
  end

  def pair(first, second)
    -> { super }.call
  end
end
p(InBlock.new.record(7))
p(InBlock.new.pair(3, 4))

built = Class.new(Recorder) do
  define_method(:pair) { |first, second| super }
end
begin
  built.new.pair(1, 2)
rescue RuntimeError => error
  p(error.message)
end

class Hidden
  undef_method :frozen?
end

class Asks < Hidden
  def frozen?
    super
  end

  def method_missing(name, *arguments)
    [:missing, name]
  end
end
p(Asks.new.frozen?)

class Named
  def label
    [:named]
  end
end

class Relabeled < Named
  def label
    [:relabeled] + super
  end
end

class Copied < Relabeled
  alias_method :tag, :label
end
p(Copied.new.tag)

module Plain
  def build
    :plain
  end
end

module Wrapped
  def build
    [:wrapped, super]
  end
end

class Factory
  extend Plain
  extend Wrapped
end
p(Factory.build)

module Sends
  def __send__(name, *arguments)
    super
  end
end

class Sender
  include Sends

  def answer
    42
  end
end
p(Sender.new.__send__(:answer))

Output:

[[10, 2, :added, 5], {flag: :off}]
[[10, 3, 4, :added, 5], {flag: :on}]
[:changed, :b]
[[], {}]
[3, 4]
"implicit argument passing of super from method defined by define_method() is not supported. Specify all arguments explicitly."
[:missing, :frozen?]
[:relabeled, :named]
[:wrapped, :plain]
42