Spec-Zone.ru › Ruby 2.7

класс Delegator

Родитель:
BasicObject

Эта библиотека предоставляет три различных способа делегирования вызовов методов объекту. Самый простой в использовании — SimpleDelegator. Передайте объект в конструктор, и все методы, поддерживаемые объектом, будут делегированы. Этот объект можно изменить позже.

Для дальнейшего расширения, метод DelegateClass верхнего уровня позволяет легко настроить делегирование через наследование классов. Это значительно гибче и, вероятно, является наиболее распространённым использованием этой библиотеки.

Наконец, если вам нужен полный контроль над схемой делегирования, вы можете унаследовать от абстрактного класса Delegator и настроить его по мере необходимости. (Если вы обнаружили, что вам нужен такой контроль, взгляните на Forwardable, который также находится в стандартной библиотеке. Он может лучше подойти для ваших нужд.)

Реализация SimpleDelegator служит хорошим примером использования Delegator:

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

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

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

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

Методы экземпляра

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Вызывается метод суперкласса
marshal_dump() Показать исходный код
# File lib/delegate.rb, line 199
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 211
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 78
               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 127
def methods(all=true)
  __getobj__.methods(all) | super
end

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

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

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

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

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

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

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

Также алиасировано как: __raise__
respond_to_missing?(m, include_private) Показать исходный код
# File lib/delegate.rb, line 95
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 110
        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–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

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