─問題─

Ruby2.0におけるモジュールに関し次の問に答えよ(各5点、制限時間5分)。

問1

以下のコードにおける出力を答えよ。

class A
  def initialize
    print :a
    super
  end

  def initialize
    print :A
    super
  end
end

A.new


問2

以下のコードにおける出力を答えよ。

module B
  def initialize
    print :B
    super
  end
end

class A
  include B

  def initialize
    print :A
    super
  end
end

A.new


問3

以下のコードにおける出力を答えよ。

module C
  def initialize
    print :C
    super
  end
end

module B
  def initialize
    print :B
    super
  end
end

class A
  include C
  include B

  def initialize
    print :A
    super
  end
end

A.new


問4

以下のコードにおける出力を答えよ。

module C
  def initialize
    print :C
    super
  end
end

module B
  def self.included(base)
    base.send :include, C
  end

  def initialize
    print :B
    super
  end
end

class A
  include B

  def initialize
    print :A
    super
  end
end

A.new


問5

問4における状態から最小の改変で出力をCABとしたい。どうすればいいか。




─答え─

問1

正解: A

解説: 前方のメソッドが後方のメソッドで上書きされるから。


問2

正解: AB

解説: `include B`により継承順位が`A -> B`となり、A#initializeにおけるsuperでB#initializeが呼ばれるから。継承順位はA.ancestorsで確認できます。


問3

正解: ABC

解説:includeの順位により継承順位が`A -> B -> C`となり、A#initializeにおけるsuperでB#initializeが呼ばれ、次いでB#initializeにおけるsuperでC#initializeが呼ばれるから。


問4

正解: ACB

解説: クラスAにBがincludeされたときに、B.includedメソッドが呼び出されてAにCがincludeされることとなり、継承順位は`A -> C -> B`となるから。


問5

正解:B.included内の`include`を`prepend`に書き換える。

解説: Module#prependはクラスAの前にモジュールCを差し込み、継承順位を`C -> A -> B`とします。
module C
  def initialize
    print :C
    super
  end
end

module B
  def self.included(base)
    base.send :prepend, C
  end

  def initialize
    print :B
    super
  end
end

class A
  include B

  def initialize
    print :A
    super
  end
end

A.new

頭の整理ついでに問題にしてみました。



blog comments powered by Disqus
ruby_pack8

100円〜で好評発売中!
M'ELBORNE BOOKS