Class: Delegator

Inherits:
BasicObject
Defined in:
lib/delegate.rb

Overview

Delegator is an abstract class used to build delegator pattern objects from subclasses. Subclasses should redefine _getobj_. For a concrete implementation, see SimpleDelegator.

Direct Known Subclasses

SimpleDelegator

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(obj) ⇒ Delegator

Pass in the obj to delegate method calls to. All methods supported by obj will be delegated to.



136
137
138
# File 'lib/delegate.rb', line 136

def initialize(obj)
  __setobj__(obj)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &block) ⇒ Object

Handles the magic of delegation through _getobj_.



143
144
145
146
147
148
149
150
# File 'lib/delegate.rb', line 143

def method_missing(m, *args, &block)
  target = self.__getobj__
  begin
    target.respond_to?(m) ? target.__send__(m, *args, &block) : super(m, *args, &block)
  ensure
    $@.delete_if {|t| %r"\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}:"o =~ t} if $@
  end
end

Class Method Details

.const_missing(n) ⇒ Object

:stopdoc:



127
128
129
# File 'lib/delegate.rb', line 127

def self.const_missing(n)
  ::Object.const_get(n)
end

.delegating_block(mid) ⇒ Object

:stopdoc:



334
335
336
337
338
339
340
341
342
343
# File 'lib/delegate.rb', line 334

def Delegator.delegating_block(mid)
  lambda do |*args, &block|
    target = self.__getobj__
    begin
      target.__send__(mid, *args, &block)
    ensure
      $@.delete_if {|t| /\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}:/o =~ t} if $@
    end
  end
end

.public_apiObject

:nodoc:



296
297
298
# File 'lib/delegate.rb', line 296

def self.public_api   # :nodoc:
  @delegator_api
end

Instance Method Details

#!Object



207
208
209
# File 'lib/delegate.rb', line 207

def !
  !__getobj__
end

#!=(obj) ⇒ Object

Returns true if two objects are not considered of equal value.



202
203
204
205
# File 'lib/delegate.rb', line 202

def !=(obj)
  return false if obj.equal?(self)
  __getobj__ != obj
end

#==(obj) ⇒ Object

Returns true if two objects are considered of equal value.



194
195
196
197
# File 'lib/delegate.rb', line 194

def ==(obj)
  return true if obj.equal?(self)
  self.__getobj__ == obj
end

#__getobj__Object

This method must be overridden by subclasses and should return the object method calls are being delegated to.

Raises:

  • (NotImplementedError)


215
216
217
# File 'lib/delegate.rb', line 215

def __getobj__
  raise NotImplementedError, "need to define `__getobj__'"
end

#__setobj__(obj) ⇒ Object

This method must be overridden by subclasses and change the object delegate to obj.

Raises:

  • (NotImplementedError)


223
224
225
# File 'lib/delegate.rb', line 223

def __setobj__(obj)
  raise NotImplementedError, "need to define `__setobj__'"
end

#freezeObject

Freeze self and target at once.



290
291
292
293
# File 'lib/delegate.rb', line 290

def freeze
  __getobj__.freeze
  super
end

#marshal_dumpObject

Serialization support for the object returned by _getobj_.



230
231
232
233
234
235
236
237
# File 'lib/delegate.rb', line 230

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) ⇒ Object

Reinitializes delegation from a serialized object.



242
243
244
245
246
247
248
249
250
# File 'lib/delegate.rb', line 242

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

#methodsObject

Returns the methods available to this delegate object as the union of this object's and _getobj_ methods.



169
170
171
# File 'lib/delegate.rb', line 169

def methods
  __getobj__.methods | super
end

#protected_methods(all = true) ⇒ Object

Returns the methods available to this delegate object as the union of this object's and _getobj_ protected methods.



185
186
187
# File 'lib/delegate.rb', line 185

def protected_methods(all=true)
  __getobj__.protected_methods(all) | super
end

#public_methods(all = true) ⇒ Object

Returns the methods available to this delegate object as the union of this object's and _getobj_ public methods.



177
178
179
# File 'lib/delegate.rb', line 177

def public_methods(all=true)
  __getobj__.public_methods(all) | super
end

#respond_to_missing?(m, include_private) ⇒ Boolean

Checks for a method provided by this the delegate object by forwarding the call through _getobj_.

Returns:

  • (Boolean)


156
157
158
159
160
161
162
163
# File 'lib/delegate.rb', line 156

def respond_to_missing?(m, include_private)
  r = self.__getobj__.respond_to?(m, include_private)
  if r && include_private && !self.__getobj__.respond_to?(m, false)
    warn "#{caller(3)[0]}: delegator does not forward private method \##{m}"
    return false
  end
  r
end