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
公開類別方法
new(obj) 按一下以切換來源
傳入要將方法呼叫委派給的 obj。obj 支援的所有方法都將被委派。
# File lib/delegate.rb, line 75 def initialize(obj) __setobj__(obj) end
公開實例方法
!() 按一下以切換來源
將 ! 委派給 _getobj_
# File lib/delegate.rb, line 180 def ! !__getobj__ end
!=(obj) 按一下以切換來源
如果兩個物件不被視為等值,則傳回 true。
# File lib/delegate.rb, line 164 def !=(obj) return false if obj.equal?(self) __getobj__ != obj end
==(obj) 按一下以切換來源
如果兩個物件被視為等值,則傳回 true。
# File lib/delegate.rb, line 156 def ==(obj) return true if obj.equal?(self) self.__getobj__ == obj end
__getobj__() 按一下以切換原始碼
子類別必須覆寫此方法,並傳回物件方法呼叫委派到的目標。
# File lib/delegate.rb, line 188 def __getobj__ __raise__ ::NotImplementedError, "need to define `__getobj__'" end
__setobj__(obj) 按一下以切換原始碼
子類別必須覆寫此方法,並將物件委派變更為 obj。
# File lib/delegate.rb, line 196 def __setobj__(obj) __raise__ ::NotImplementedError, "need to define `__setobj__'" end
eql?(obj) 按一下以切換原始碼
如果兩個物件被視為等值,則傳回 true。
# File lib/delegate.rb, line 172 def eql?(obj) return true if obj.equal?(self) obj.eql?(__getobj__) end
freeze() 按一下以切換原始碼
:method: freeze 凍結 _getobj_ 傳回的物件和 self。
呼叫超類別方法
# File lib/delegate.rb, line 237 def freeze __getobj__.freeze super() end
marshal_dump() 按一下以切換原始碼
_getobj_ 傳回的物件的序列化支援。
# 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
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) 按一下以切換原始碼
呼叫超類別方法
BasicObject#method_missing
# 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
methods(all=true) 按一下以切換原始碼
傳回此委派物件可用的方法,為此物件和 _getobj_ 方法的聯集。
呼叫超類別方法
# File lib/delegate.rb, line 131 def methods(all=true) __getobj__.methods(all) | super end
protected_methods(all=true) 按一下以切換原始碼
傳回此委派物件可用的方法,為此物件和 _getobj_ 受保護方法的聯集。
呼叫超類別方法
# File lib/delegate.rb, line 147 def protected_methods(all=true) __getobj__.protected_methods(all) | super end
public_methods(all=true) 按一下以切換原始碼
傳回此委派物件可用的方法,為此物件和 _getobj_ 公用方法的聯集。
呼叫超類別方法
# File lib/delegate.rb, line 139 def public_methods(all=true) __getobj__.public_methods(all) | super end
raise() 按一下以切換原始碼
別名:__raise__
respond_to_missing?(m, include_private) 按一下以切換原始碼
透過轉送呼叫至 _getobj_,檢查委派物件提供的某個方法。
# 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
私人執行個體方法
target_respond_to?(target, m, include_private) 按一下以切換原始碼
處理 BasicObject
執行個體
# 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