instance method
Object#DelegateClass
(::Class) -> ::Class
DelegateClass(superclass, &block)
lib/delegate.rb
View on GitHub ↗
# File tmp/rubies/ruby-4.0.0/lib/delegate.rb, line 395
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
normal, special = public_instance_methods.partition { |m| m.match?(/\A[a-zA-Z]\w*[!\?]?\z/) }
source = normal.map do |method|
"def #{method}(...); __getobj__.#{method}(...); end"
end
protected_instance_methods.each do |method|
source << "def #{method}(...); __getobj__.__send__(#{method.inspect}, ...); end"
end
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
class_eval(source.join(";"), __FILE__, __LINE__)
special.each do |method|
define_method(method, Delegator.delegating_block(method))
end
protected(*protected_instance_methods)
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
The primary interface to this library. Use to setup delegation when defining your class.
Example
class MyClass < DelegateClass(ClassToDelegateTo) # Step 1 def initialize super(obj_of_ClassToDelegateTo) # Step 2 end end
or:
Example
MyClass = DelegateClass(ClassToDelegateTo) do # Step 1 def initialize super(obj_of_ClassToDelegateTo) # Step 2 end end
Here’s a sample of use from Tempfile which is really a File object with a few special rules about storage location and when the File should be deleted. That makes for an almost textbook perfect example of how to use delegation.
Example
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