класс Delegator
Эта библиотека предоставляет три разных способа делегирования вызовов методов объекту. Самый простой в использовании — SimpleDelegator. Передайте объект в конструктор, и все методы, поддерживаемые объектом, будут делегированы. Этот объект можно изменить позже.
Для более продвинутого подхода, метод DelegateClass верхнего уровня позволяет легко настроить делегирование через наследование классов. Это значительно более гибко и, следовательно, вероятно, является наиболее распространённым использованием этой библиотеки.
Наконец, если вам нужен полный контроль над схемой делегирования, вы можете унаследовать от абстрактного класса Delegator и настроить его по мере необходимости. (Если вы обнаружите необходимость в этом контроле, ознакомьтесь с Forwardable, который также входит в стандартную библиотеку. Он может лучше подойти для ваших нужд.)
Реализация SimpleDelegator служит хорошим примером использования Delegator:
require 'delegate'
class SimpleDelegator < Delegator
def __getobj__
@delegate_sd_obj # return object we are delegating to, required
end
def __setobj__(obj)
@delegate_sd_obj = obj # change delegation object,
# a feature we're providing
end
end
Примечания
Обратите внимание, RDoc не будет обнаруживать делегированные методы.
Константы
- KERNEL_RESPOND_TO
- VERSION
Методы публичного класса
Исходный код
# File lib/delegate.rb, line 75 def initialize(obj) __setobj__(obj) end
Передайте obj для делегирования вызовов методов. Все методы, поддерживаемые obj, будут делегированы.
Методы публичного экземпляра
Исходный код
# File lib/delegate.rb, line 164 def !=(obj) return false if obj.equal?(self) __getobj__ != obj end
Возвращает true, если два объекта не считаются равными по значению.
Исходный код
# File lib/delegate.rb, line 156 def ==(obj) return true if obj.equal?(self) self.__getobj__ == obj end
Возвращает true, если два объекта считаются равными по значению.
Исходный код
# File lib/delegate.rb, line 188 def __getobj__ __raise__ ::NotImplementedError, "need to define '__getobj__'" end
Этот метод должен быть переопределен подклассами и должен возвращать объект, к которому делегируются вызовы методов.
Исходный код
# File lib/delegate.rb, line 196 def __setobj__(obj) __raise__ ::NotImplementedError, "need to define '__setobj__'" end
Этот метод должен быть переопределен подклассами и изменить объект-делегат на obj.
Исходный код
# File lib/delegate.rb, line 172 def eql?(obj) return true if obj.equal?(self) obj.eql?(__getobj__) end
Возвращает true, если два объекта считаются равными по значению.
Исходный код
# File lib/delegate.rb, line 237 def freeze __getobj__.freeze super() end
:method: freeze Замораживает объект, возвращаемый _getobj_, и self.
Исходный код
# File lib/delegate.rb, line 203
def marshal_dump
ivars = instance_variables.reject {|var| /\A@delegate_/ =~ var}
[
:__v2__,
ivars, ivars.map {|var| instance_variable_get(var)},
__getobj__
]
end Поддержка сериализации для объекта, возвращаемого _getobj_.
Исходный код
# File lib/delegate.rb, line 215
def marshal_load(data)
version, vars, values, obj = data
if version == :__v2__
vars.each_with_index {|var, i| instance_variable_set(var, values[i])}
__setobj__(obj)
else
__setobj__(data)
end
end Переинициализирует делегирование из сериализованного объекта.
Исходный код
# File lib/delegate.rb, line 82
def method_missing(m, *args, &block)
r = true
target = self.__getobj__ {r = false}
if r && target_respond_to?(target, m, false)
target.__send__(m, *args, &block)
elsif ::Kernel.method_defined?(m) || ::Kernel.private_method_defined?(m)
::Kernel.instance_method(m).bind_call(self, *args, &block)
else
super(m, *args, &block)
end
end BasicObject#method_missing Исходный код
# File lib/delegate.rb, line 131 def methods(all=true) __getobj__.methods(all) | super end
Возвращает методы, доступные для этого объекта-делегата, как объединение методов этого объекта и _getobj_.
Исходный код
# File lib/delegate.rb, line 147 def protected_methods(all=true) __getobj__.protected_methods(all) | super end
Возвращает методы, доступные для этого объекта-делегата, как объединение защищенных методов этого объекта и _getobj_.
Исходный код
# File lib/delegate.rb, line 139 def public_methods(all=true) __getobj__.public_methods(all) | super end
Возвращает методы, доступные для этого объекта-делегата, как объединение публичных методов этого объекта и _getobj_.
Исходный код
# File lib/delegate.rb, line 66
Используйте __raise__, если у вашего Delegator нет объекта для делегирования вызова метода raise.
Исходный код
# File lib/delegate.rb, line 99
def respond_to_missing?(m, include_private)
r = true
target = self.__getobj__ {r = false}
r &&= target_respond_to?(target, m, include_private)
if r && include_private && !target_respond_to?(target, m, false)
warn "delegator does not forward private method \##{m}", uplevel: 3
return false
end
r
end Проверяет наличие метода, предоставляемого объектом-делегатом, передавая вызов через _getobj_.
Скрытые методы экземпляра
Исходный код
# File lib/delegate.rb, line 114
def target_respond_to?(target, m, include_private)
case target
when Object
target.respond_to?(m, include_private)
else
if KERNEL_RESPOND_TO.bind_call(target, :respond_to?)
target.respond_to?(m, include_private)
else
KERNEL_RESPOND_TO.bind_call(target, m, include_private)
end
end
end Обработка экземпляров BasicObject
Ruby Core © 1993–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.