Ruby 2.4

Forwardable

module Forwardable

可转换模块使用方法def_delegator和def_delegators将指定方法委托给指定的对象。

例如,假设你有一个RecordCollection类,它包含一个数组@records。您可以提供查找方法record_number(),该方法只需在@records数组中调用[] ,如下所示:

require 'forwardable' class RecordCollection attr_accessor :records extend Forwardable def_delegator :@records, :[], :record_number end

我们可以像这样使用查找方法:

r = RecordCollection.new r.records = [4,5,6] r.record_number(0) # => 4

此外,如果您希望提供方法大小,<

class RecordCollection # re-open RecordCollection class def_delegators :@records, :size, :<<, :map end r = RecordCollection.new r.records = [1,2,3] r.record_number(0) # => 1 r.size # => 3 r << 4 # => [1, 2, 3, 4] r.map { |x| x * 2 } # => [2, 4, 6, 8]

您甚至可以使用Forwardable扩展常规对象。

my_hash = Hash.new my_hash.extend Forwardable # prepare object for delegation my_hash.def_delegator "STDOUT", "puts" # add delegation for STDOUT.puts() my_hash.puts "Howdy!"

另一个例子

我们希望依靠之前明显发生的事情,但通过授权,我们可以只采用我们需要的方法,甚至适当地重命名它们。在许多情况下,这比继承更可取,这使我们可以使用完整的旧界面,即使其中大部分都不需要。

class Queue extend Forwardable def initialize @q = [ ] # prepare delegate object end # setup preferred interface, enq() and deq()... def_delegator :@q, :push, :enq def_delegator :@q, :shift, :deq # support some general Array methods that fit Queues well def_delegators :@q, :clear, :first, :push, :shift, :size end q = Queue.new q.enq 1, 2, 3, 4, 5 q.push 6 q.shift # => 1 while q.size > 0 puts q.deq end q.enq "Ruby", "Perl", "Python" puts q.first q.clear puts q.first

这应该输出:

2 3 4 5 6 Ruby nil

注意

请注意,RDoc不会检测委托方法。

forwardable.rb通过#def_delegator和#def_delegators方法提供单方法委托。对于通过DelegateClass的full-class授权,请参阅delegate.rb

常量

FORWARDABLE_VERSION

forwardable.rb版本

属性

debugRW

ignored

Public Instance Methods

def_delegator(accessor, method, ali = method)

Alias for: def_instance_delegator

def_delegators(accessor, *methods)

Alias for: def_instance_delegators

def_instance_delegator(accessor, method, ali = method) Show source

使用可选的别名名称定义method为委托人实例方法ali。方法调用ali将被委托给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

# File lib/forwardable.rb, line 179 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

Also aliased as: def_delegator

def_instance_delegators(accessor, *methods) Show source

用于定义多个委托人方法的快捷方式,但没有规定使用不同的名称。以下两个代码示例具有相同的效果:

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

# File lib/forwardable.rb, line 152 def def_instance_delegators(accessor, *methods) methods.delete("__send__") methods.delete("__id__") for method in methods def_instance_delegator(accessor, method) end end

Also aliased as: def_delegators

delegate(hash)

Alias for: instance_delegate

delegate method → accessor Show source

delegate method, method, ... → accessor

以散列为参数。关键是一个符号或一系列符号。这些符号对应于方法名称。该值是该方法将被委派到的访问器。

# File lib/forwardable.rb, line 131 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

Also aliased as: delegate