Reputation: 105133
Here is my class:
class Book
def read
# something
end
end
And another one:
class Magazine
def read
# something
end
end
Now, I want to decorate both read
methods in these two classes. I want them both to print "hello" right before they start working. How do I do that? I suspect, I need to use mixins, but can't figure out exactly how.
Upvotes: 1
Views: 285
Reputation: 98
You can prepend
module:
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"
As well there is more clean way to do this kind of modifications with 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"
Notice: this code may not run in irb
.
Also you can do it right in the runtime:
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"
Upvotes: 4
Reputation: 365
May be you want something as:
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
Upvotes: 1