Module: Forwardable

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

Overview

:stopdoc:

Constant Summary collapse

VERSION =

Version of forwardable.rb

"1.3.1"
FORWARDABLE_VERSION =
VERSION

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.debugObject

ignored


118
119
120
# File 'lib/forwardable.rb', line 118

def debug
  @debug
end

Class Method Details

._compile_method(src, file, line) ⇒ Object


13
14
15
# File 'lib/forwardable/impl.rb', line 13

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

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

:nodoc:


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
230
231
232
233
234
# File 'lib/forwardable.rb', line 198

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}
      end
    end
  end;
end

._valid_method?(method) ⇒ Boolean

Returns:

  • (Boolean)

3
4
5
6
7
8
9
10
11
# File 'lib/forwardable/impl.rb', line 3

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. accessor should be a method name, instance variable name, or constant name. Use the full path to the constant if providing the constant name. Returns the name of the method defined.

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

  def_delegator :@queue, :push, :mypush
  def_delegator 'MyQueue::CONST', :to_i
end

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

183
184
185
186
187
188
189
190
191
# File 'lib/forwardable.rb', line 183

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
  mod = Module === self ? self : singleton_class
  ret = mod.module_eval(&gen)
  mod.send(:ruby2_keywords, ali) if RUBY_VERSION >= '2.7'
  ret
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

151
152
153
154
155
156
# File 'lib/forwardable.rb', line 151

def def_instance_delegators(accessor, *methods)
  methods.each do |method|
    next if /\A__(?:send|id)__\z/ =~ method
    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, instance variable names, or constant names (see def_delegator). The value is the accessor to which the methods will be delegated.

:call-seq:

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

130
131
132
133
134
135
136
137
138
# File 'lib/forwardable.rb', line 130

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