类 Object
公共实例方法
DelegateClass(superclass, &block) 点击切换源代码
此库的主要接口。在定义类时使用它来设置委托。
class MyClass < DelegateClass(ClassToDelegateTo) # Step 1 def initialize super(obj_of_ClassToDelegateTo) # Step 2 end end
或
MyClass = DelegateClass(ClassToDelegateTo) do # Step 1 def initialize super(obj_of_ClassToDelegateTo) # Step 2 end end
这里有一个来自 Tempfile 的使用示例,它实际上是一个 File 对象,有一些关于存储位置和何时删除该 File 的特殊规则。这构成了一个关于如何使用委托的几乎完美的教科书例子。
class Tempfile < DelegateClass(File) # constant and class member data initialization... def initialize(basename, tmpdir=Dir::tmpdir) # build up file path/name in var tmpname... @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600) # ... super(@tmpfile) # below this point, all methods of File are supported... end # ... end
调用父类方法
# File delegate.rb, line 394 def DelegateClass(superclass, &block) klass = Class.new(Delegator) ignores = [*::Delegator.public_api, :to_s, :inspect, :=~, :!~, :===] protected_instance_methods = superclass.protected_instance_methods protected_instance_methods -= ignores public_instance_methods = superclass.public_instance_methods public_instance_methods -= ignores klass.module_eval do def __getobj__ # :nodoc: unless defined?(@delegate_dc_obj) return yield if block_given? __raise__ ::ArgumentError, "not delegated" end @delegate_dc_obj end def __setobj__(obj) # :nodoc: __raise__ ::ArgumentError, "cannot delegate to self" if self.equal?(obj) @delegate_dc_obj = obj end protected_instance_methods.each do |method| define_method(method, Delegator.delegating_block(method)) protected method end public_instance_methods.each do |method| define_method(method, Delegator.delegating_block(method)) end end klass.define_singleton_method :public_instance_methods do |all=true| super(all) | superclass.public_instance_methods end klass.define_singleton_method :protected_instance_methods do |all=true| super(all) | superclass.protected_instance_methods end klass.define_singleton_method :instance_methods do |all=true| super(all) | superclass.instance_methods end klass.define_singleton_method :public_instance_method do |name| super(name) rescue NameError raise unless self.public_instance_methods.include?(name) superclass.public_instance_method(name) end klass.define_singleton_method :instance_method do |name| super(name) rescue NameError raise unless self.instance_methods.include?(name) superclass.instance_method(name) end klass.module_eval(&block) if block return klass end