Ключевое слово super
в Ruby используется для вызова метода с тем же именем из родительского класса (или включенного модуля). Это мощный инструмент для:
class Parent
def greet(name)
"Hello, #{name}!"
end
end
class Child < Parent
def greet(name)
super + " How are you?" # Передает name автоматически
end
end
Child.new.greet("Alice") # => "Hello, Alice! How are you?"
class Parent
def initialize
@created_at = Time.now
end
end
class Child < Parent
def initialize
super() # Явный вызов без аргументов
@child_init = true
end
end
class Calculator
def add(a, b)
a + b
end
end
class ScientificCalculator < Calculator
def add(a, b)
"Result: #{super(a, b)}" # Явная передача аргументов
end
end
super
ищет метод в:
super
работает в:
class A
def self.class_method
"Parent class method"
end
end
class B < A
def self.class_method
super + " extended"
end
end
B.class_method # => "Parent class method extended"
При вызове super
блок передается автоматически:
class Parent
def wrap
yield
end
end
class Child < Parent
def wrap
super { "Wrapped: #{yield}" }
end
end
Child.new.wrap { "content" } # => "Wrapped: content"
class Product
def initialize(name)
@name = name
end
end
class Book < Product
def initialize(name, author)
super(name) # Передаем только name
@author = author
end
end
class Logger
def log(message)
puts message
end
end
class TimestampLogger < Logger
def log(message)
super("[#{Time.now}] #{message}")
end
end
class BasicArray
def initialize(*elements)
@elements = elements
end
def to_s
@elements.join(', ')
end
end
class DecoratedArray < BasicArray
def to_s
"Array: #{super}"
end
end
class A
def method
super # Будет искать method в родителях
end
end
def method(a, b)
super # Передаст все аргументы, даже если родитель ожидает другое количество
end
class Parent
def method(a)
end
end
class Child < Parent
def method(a, b) # Изменяем сигнатуру
super(a) # Нужно явно указать аргумент
end
end
При использовании prepend
super будет ссылаться на следующую версию метода в цепочке:
module Interceptor
def save
puts "Before save"
super
puts "After save"
end
end
class Document
prepend Interceptor
def save
puts "Saving..."
end
end
Document.new.save
# Вывод:
# Before save
# Saving...
# After save
Работает аналогично методам экземпляра:
class Parent
def self.setup
@config ||= {}
end
end
class Child < Parent
def self.setup
super.tap { |c| c[:child] = true }
end
end
Резюмируем: super
в Ruby — это гибкий инструмент для работы с наследованием, позволяющий повторно использовать и расширять функциональность родительских классов. Понимание его поведения с разными типами аргументов, в различных контекстах и при работе с модулями критически важно для профессиональной разработки на Ruby. Правильное использование super помогает создавать чистый, поддерживаемый код с минимальным дублированием.