Duplicate methods in modules in Ruby

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:

  1. (in Ruby 2.0 and newer) Replace include with prepend so that the module is ahead of the entire method lookup chain (except perhaps after the metaclass, but that's already wild).
  2. Move the call to super to Library::Book (and remember that calling super with no arguments or parentheses rolls over the arguments of the current call).
Scroll to Top