Spec-Zone.ru › Ruby 4.0

класс 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 не обнаруживает делегируемые методы.

Константы

VERSION

Строка версии

Публичные методы класса

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

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

Публичные методы экземпляра

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

Делегирует вызов ! объекту __getobj__

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Spec-Zone.ru

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