2014年4月7日月曜日

Rubyでクラスが継承されたら何かする

Rubyではクラスが継承されると親クラスのClass#inheritedというメソッドが呼ばれる。

class Foo
  def self.inherited(subclass)
    puts "#{self} is inherited by #{subclass}"
  end
end

class Bar < Foo
end

Baz = Class.new(Foo)
Foo is inherited by Bar
Foo is inherited by #<Class:0x007fdd11969330>

Class.newでサブクラスを生成すると無名のクラスが生成されて、最初に定数に代入されたタイミングでクラスの名前が設定されるというキモい仕様があるので、Class.new(Foo)のタイミングでは名前が出ていない。

Class#inheritedが呼ばれるタイミングは「クラス定義文の実行直前」とのことなので、上記のBarクラスにあれこれメソッドとか定義してあっても、inheritedが呼ばれた段階ではまだ記述したメソッドが存在しないことに注意。
ちょうど上記のように単に継承しただけの状態と同じクラスになっている。

似たようなものにModule#includedModule#extendedがある。それぞれモジュールがinclude/extendされた時に呼ばれる。

こんな機能を使うことはそうそうないと思うけど、仕事で使ってたとあるライブラリではプラグインを自動的にプラグインマネージャ的なものに登録する仕組みとして使われていた。

参考

0 件のコメント:

コメントを投稿