Top Level Namespace
Defined Under Namespace
Classes: Delegator, SimpleDelegator
Instance Method Summary collapse
-
#DelegateClass(superclass) ⇒ Object
The primary interface to this library.
Instance Method Details
#DelegateClass(superclass) ⇒ Object
The primary interface to this library. Use to setup delegation when defining your class.
class MyClass < DelegateClass(ClassToDelegateTo) # 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.
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
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
# File 'lib/delegate.rb', line 378 def DelegateClass(superclass) klass = Class.new(Delegator) methods = superclass.instance_methods methods -= ::Delegator.public_api methods -= [:to_s,:inspect,:=~,:!~,:===] 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 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.protected_instance_methods end klass.define_singleton_method :protected_instance_methods do |all=true| super(all) | superclass.protected_instance_methods end return klass end |