Question:
You need to add a module that adds an array to an object. For some reason, this code does not work, there is no access to the @comments array in methods
module Library
module Commentable
attr_accessor :comments
def initialize author, title
@comments = []
super author, title
end
end
end
class Library::Book
include Library::Commentable
attr_accessor :author, :title
def initialize author, title
@author = author
@title = title
end
end
Answer:
Because it turns out that initialize
is called first on Library::Book
, which the inherited method (from Commentable
) does not call ( super
is not there).
Library::Book.ancestors
#=> [
# Library::Book, <-- он первый по списку
# Library::Commentable,
# Object,
# Kernel,
# BasicObject
# ]
If you forget about the fact that your "commented" for some reason takes arguments characteristic of the book (because this is a detail of the problem that you did not say anything about), there are two possible ways out:
- (in Ruby 2.0 and newer) Replace
include
withprepend
so that the module is ahead of the entire method lookup chain (except perhaps after the metaclass, but that's already wild). - Move the call to
super
toLibrary::Book
(and remember that callingsuper
with no arguments or parentheses rolls over the arguments of the current call).