将String功能添加到类

Nie*_* B. 3 ruby string delegates

考虑这个课程

class Duck
  attr_accessor :name

  def initialize(name)
    @name = name || 'Donald'
  end

  # Some quacking methods..

  def to_s
    "#{@name} (Duck)"
  end

end
Run Code Online (Sandbox Code Playgroud)

我想我的鸭子像方法应对upcase,sub,gsub,等,所以我可以做

my_duck = Duck.new("Scrooge")
my_duck.upcase  
   --> "SCROOGE (DUCK)"
Run Code Online (Sandbox Code Playgroud)

除了手动实现这些方法之外,还有一种非常好的方法我可以选择不会自我变异的String方法并自动让我的类响应那些,然后调用to_s然后在结果字符串上调用方法吗?

tor*_*o2k 7

您可以使用该Forwardable模块:

require 'forwardable'

class Duck      
  extend Forwardable

  # This defines Duck#upcase and Duck#sub, you can
  # add as many methods as you like.
  def_delegators(:to_s, :upcase, :sub) 

  # All the other code here... 
end

Duck.new('duffy').upcase
# => DUFFY (DUCK)

Duck.new('rubber').respond_to?(:upcase)
# => true
Run Code Online (Sandbox Code Playgroud)

通常,调用def_delegators(:foo, :bar)等同于bar手动定义方法,如下所示:

def bar(*args, &block)
  foo.bar(*args, &block)
end
Run Code Online (Sandbox Code Playgroud)

第一个参数def_delegators可以是实例变量的名称,即def_delegators(:@foo, :bar, :baz).