Это было бы относительно легко с методом класса, определенным в собственном классе верхнего уровня.
class Animal
def speak; :ok; end
def self.override *ms
ms = ms - Animal.instance_methods
puts "⚠️ #{ms.inspect} method(s) missing " \
"in #{self}’s ancestors" unless ms.empty?
end
end
class Dog < Animal
override :speak
def speak; :ok; end
override :eat
def eat; :ok; end
end
Выше было бы напечатано
# ⚠️ [:eat] method(s) missing in Dog’s ancestors
Вызов override
здесьаналогично вызову Module#module_function
с аргументом и может быть помещен в любое место кода, принимая столько имен методов, сколько необходимо.
Это также может быть выполнено с помощью переменной экземпляра eigenclass, чтобы сделатьэто больше похоже на версию Java.
class Animal
def speak
:ok
end
def self.inherited(base)
base.instance_variable_set(:@override, ->(*ms) {
ms = ms - Animal.instance_methods
puts "⚠️ #{ms.inspect} method(s) without super" \
unless ms.empty?
})
end
end
class Dog < Animal
@override[:speak]
def speak; :ok; end
@override[:eat]
def eat; :ok; end
end
Также возможно полностью копировать синтаксис Java с помощью TracePoint
и / илиModule#method_added
но я нахожу это менее явным и избегал бы прямой передачи имени метода, как показано выше.