Spec-Zone.ru › Ruby 3

класс Delegator

Родитель:
BasicObject

Эта библиотека предоставляет три разных способа делегирования вызовов методов объекту. Самый простой в использовании — 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

Методы класса Public

new(obj) Показать исходный код
# File lib/delegate.rb, line 75
def initialize(obj)
  __setobj__(obj)
end

Передайте obj для делегирования вызовов методов. Все методы, поддерживаемые obj, будут делегированы.

Методы объекта Public

!() Показать исходный код
# File lib/delegate.rb, line 180
def !
  !__getobj__
end

Делегирует ! в _getobj_

!=(obj) Показать исходный код
# File lib/delegate.rb, line 164
def !=(obj)
  return false if obj.equal?(self)
  __getobj__ != obj
end

Возвращает true, если два объекта не считаются равными по значению.

==(obj) Показать исходный код
# File lib/delegate.rb, line 156
def ==(obj)
  return true if obj.equal?(self)
  self.__getobj__ == obj
end

Возвращает true, если два объекта считаются равными по значению.

__getobj__() Показать исходный код
# File lib/delegate.rb, line 188
def __getobj__
  __raise__ ::NotImplementedError, "need to define `__getobj__'"
end

Этот метод должен быть переопределен подклассами и должен возвращать объект, к которому делегируются вызовы методов.

__raise__()
Псевдоним для: raise
__setobj__(obj) Показать исходный код
# File lib/delegate.rb, line 196
def __setobj__(obj)
  __raise__ ::NotImplementedError, "need to define `__setobj__'"
end

Этот метод должен быть переопределен подклассами и изменить объект-делегат на obj.

eql?(obj) Показать исходный код
# File lib/delegate.rb, line 172
def eql?(obj)
  return true if obj.equal?(self)
  obj.eql?(__getobj__)
end

Возвращает true, если два объекта считаются равными по значению.

freeze() Показать исходный код
# File lib/delegate.rb, line 237
def freeze
  __getobj__.freeze
  super()
end

:method: freeze Замораживает как возвращаемый объектом _getobj_, так и сам объект.

Вызывается метод суперкласса
marshal_dump() Показать исходный код
# 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_.

marshal_load(data) Показать исходный код
# 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

Переинициализирует делегирование из сериализованного объекта.

method_missing(m, *args, &block) Показать исходный код
# 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
methods(all=true) Показать исходный код
# File lib/delegate.rb, line 131
def methods(all=true)
  __getobj__.methods(all) | super
end

Возвращает методы, доступные этому объекту-делегату, как объединение методов этого объекта и _getobj_.

Вызывается метод суперкласса
protected_methods(all=true) Показать исходный код
# File lib/delegate.rb, line 147
def protected_methods(all=true)
  __getobj__.protected_methods(all) | super
end

Возвращает методы, доступные этому объекту-делегату, как объединение защищенных методов этого объекта и _getobj_.

Вызывается метод суперкласса
public_methods(all=true) Показать исходный код
# File lib/delegate.rb, line 139
def public_methods(all=true)
  __getobj__.public_methods(all) | super
end

Возвращает методы, доступные этому объекту-делегату, как объединение публичных методов этого объекта и _getobj_.

Вызывается метод суперкласса
raise() Показать исходный код
# File lib/delegate.rb, line 66
  

Используйте #__raise__, если у вашего Delegator нет объекта для делегирования вызова метода raise.

Также алиасировано как: __raise__
respond_to_missing?(m, include_private) Показать исходный код
# 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_.

Приватные методы объекта

target_respond_to?(target, m, include_private) Показать исходный код
# 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–2020 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API