如何在Ruby中装饰所有类似的方法?

时间:2018-11-21 13:07:02

标签: ruby

这是我的课程:

class Book
  def read
     # something
  end
end

还有一个:

class Magazine
  def read
     # something
  end
end

现在,我要装饰这两个类中的两个read方法。我希望他们俩在开始工作之前就打印“ hello”。我怎么做?我怀疑,我需要使用mixins,但无法确切地知道如何操作。

2 个答案:

答案 0 :(得分:4)

您可以prepend模块:

module Decorator
  def read
    puts "hello"
    super
  end
end

class Book
  prepend Decorator

  def read
    puts "bye"
  end
end

class Magazine
  prepend Decorator

  def read
    puts "cya"
  end
end

Book.new.read 
# "hello"
# "bye"

Magazine.new.read
# "hello"
# "cya"

还有一种更干净的方法可以对refinements进行这种修改:

class Book
  def read
    puts "bye"
  end
end

class Magazine
  def read
    puts "cya"
  end
end

module Decorator
  def read
    puts "hello"
    super
  end
end

module DecoratedBook
  refine Book do
    prepend Decorator
  end
end

module DecoratedMagazine
  refine Magazine do
    prepend Decorator
  end
end

using DecoratedBook
using DecoratedMagazine

Book.new.read 
# "hello"
# "bye"

Magazine.new.read
# "hello"
# "cya"

注意:此代码可能无法在irb中运行。

您也可以在运行时中直接执行此操作:

module Decorator
  def read
    puts "hello"
    super
  end
end

[Book, Magazine].each do |klass|
  klass.prepend Decorator
end

Book.new.read 
# "hello"
# "bye"

Magazine.new.read
# "hello"
# "cya"

答案 1 :(得分:1)

也许您想要的东西是:

class ReaderDecorator
  def initialize(obj)
    @obj = obj
  end

  def read
    puts 'Hello'
    @obj.read
  end
end

ReaderDecorator.new(Book.new).read
ReaderDecorator.new(Magazine.new).read