Module: Forwardable

Defined in:
lib/forwardable.rb,
lib/forwardable/impl.rb

Overview

:stopdoc:

Constant Summary collapse

VERSION =

Version of forwardable.rb

"1.2.0"
FORWARDABLE_VERSION =
VERSION
FILE_REGEXP =
%r"#{Regexp.quote(File.dirname(__FILE__))}"
FILTER_EXCEPTION =
<<-'END'

      rescue ::Exception
        [email protected]_if {|s| ::Forwardable::FILE_REGEXP =~ s} unless ::Forwardable::debug
        ::Kernel::raise
END

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.debugObject

ignored



122
123
124
# File 'lib/forwardable.rb', line 122

def debug
  @debug
end

Class Method Details

._compile_method(src, file, line) ⇒ Object



21
22
23
# File 'lib/forwardable/impl.rb', line 21

def self._compile_method(src, file, line)
  eval(src, nil, file, line)
end

._delegator_method(obj, accessor, method, ali) ⇒ Object

:nodoc:



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/forwardable.rb', line 193

def self._delegator_method(obj, accessor, method, ali)
  accessor = accessor.to_s unless Symbol === accessor

  if Module === obj ?
       obj.method_defined?(accessor) || obj.private_method_defined?(accessor) :
       obj.respond_to?(accessor, true)
    accessor = "#{accessor}()"
  end

  method_call = ".__send__(:#{method}, *args, &block)"
  if _valid_method?(method)
    loc, = caller_locations(2,1)
    pre = "_ ="
    mesg = "#{Module === obj ? obj : obj.class}\##{ali} at #{loc.path}:#{loc.lineno} forwarding to private method "
    method_call = "#{<<-"begin;"}\n#{<<-"end;".chomp}"
        unless defined? _.#{method}
          ::Kernel.warn #{mesg.dump}"\#{_.class}"'##{method}', uplevel: 1
          _#{method_call}
        else
          _.#{method}(*args, &block)
        end
      end;
  end

  _compile_method("#{<<-"begin;"}\n#{<<-"end;"}", __FILE__, __LINE__+1)
    proc do
      def #{ali}(*args, &block)
        #{pre}
        begin
          #{accessor}
        end#{method_call}#{FILTER_EXCEPTION}
      end
    end
  end;
end

._valid_method?(method) ⇒ Boolean

Returns:

  • (Boolean)


11
12
13
14
15
16
17
18
19
# File 'lib/forwardable/impl.rb', line 11

def self._valid_method?(method)
  catch {|tag|
    eval("BEGIN{throw tag}; ().#{method}", binding, __FILE__, __LINE__)
  }
rescue SyntaxError
  false
else
  true
end

Instance Method Details

#def_instance_delegator(accessor, method, ali = method) ⇒ Object Also known as: def_delegator

Define method as delegator instance method with an optional alias name ali. Method calls to ali will be delegated to accessor.method.

class MyQueue
  extend Forwardable
  attr_reader :queue
  def initialize
    @queue = []
  end

  def_delegator :@queue, :push, :mypush
end

q = MyQueue.new
q.mypush 42
q.queue    #=> [42]
q.push 23  #=> NoMethodError


181
182
183
184
185
186
# File 'lib/forwardable.rb', line 181

def def_instance_delegator(accessor, method, ali = method)
  gen = Forwardable._delegator_method(self, accessor, method, ali)

  # If it's not a class or module, it's an instance
  (Module === self ? self : singleton_class).module_eval(&gen)
end

#def_instance_delegators(accessor, *methods) ⇒ Object Also known as: def_delegators

Shortcut for defining multiple delegator methods, but with no provision for using a different name. The following two code samples have the same effect:

def_delegators :@records, :size, :<<, :map

def_delegator :@records, :size
def_delegator :@records, :<<
def_delegator :@records, :map


154
155
156
157
158
159
160
# File 'lib/forwardable.rb', line 154

def def_instance_delegators(accessor, *methods)
  methods.delete("__send__")
  methods.delete("__id__")
  for method in methods
    def_instance_delegator(accessor, method)
  end
end

#instance_delegate(hash) ⇒ Object Also known as: delegate

Takes a hash as its argument. The key is a symbol or an array of symbols. These symbols correspond to method names. The value is the accessor to which the methods will be delegated.

:call-seq:

delegate method => accessor
delegate [method, method, ...] => accessor


133
134
135
136
137
138
139
140
141
# File 'lib/forwardable.rb', line 133

def instance_delegate(hash)
  hash.each do |methods, accessor|
    unless defined?(methods.each)
      def_instance_delegator(accessor, methods)
    else
      methods.each {|method| def_instance_delegator(accessor, method)}
    end
  end
end