Ruby: メタプログラミングに役立つフック系メソッド(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

Ruby: メタプログラミングに役立つフック系メソッド(翻訳)

Rubyにはさまざまなフック系メソッドがあり、これらを用いてクラスやモジュールやオブジェクトをその場で操作できます。

以下はその中でも重要度の高いフック系メソッドです。

  • Module#included
  • Module#extended
  • Module#prepended
  • Class#inherited

モジュールでincludedextendedprependedを使う

これらのフック系メソッドは、モジュールが別のモジュールやクラスにそれぞれincludeされたとき、extendされたとき、prependされたときに必ず呼び出されます。

それぞれの動作は割りと似通っていますので、ここではincludedフックメソッドを用いて詳しく説明します。

module Commentable
  def self.included(commentable_entity)
    puts "#{commentable_entity}エンティティがコメントを受け取れるようになった!"
  end\
end

class MediumPost
  include Commentable
end

上のコードの実行結果は次のとおりです。

MediumPostエンティティがコメントを受け取れるようになった!

このフックメソッドが定義されているモジュールを他のクラスやモジュールがincludeすると、それらに応じてメソッドや属性をこのように追加できます。

このメカニズムは、ActiveSupport::Concernモジュールで実際に使われています。

このメソッドの実装は、Module#extendedフックメソッドやModule#prependedフックメソッドとだいぶ似通っています。

Class#inherited

このフックメソッドが定義されているクラスがあると、そのクラスのサブクラスが作成(定義)されたときに必ず呼び出されます。

class User
  def self.inherited(user_type)
    puts "#{user_type}はユーザーの一種です"
  end
end

class Tenant < User
end

上のコードの実行結果は次のとおりです。

Tenantはユーザーの一種です

このフックメソッドは、あるクラスのサブクラスごとに変数やclass_attributeを定義したい場合に割りと便利です。

ActiveRecord::Coreモジュールの[initialize_find_by_cache](https://github.com/rails/rails/blob/master/activerecord/lib/active_record/core.rb#L151)クラスメソッドはまさにこれを行っています。

まとめ

フック系メソッドは、クラスやモジュールにその場で操作を加えたい場合になかなか有用です。

しかし、これらのフック系メソッドはモジュールやクラスの設計を改変するので、スーパークラスのメソッドがオーバーライドされるといった望ましくない副作用が生じる可能性もあります。

BasicObject#method_missingフックメソッドについてはまた別の記事で解説いたします。

それじゃまた!


本記事をお読みいただきありがとうございました☺。

お役に立ちましたら、ぜひ本記事への 👏や共有をお願いします。

関連記事

異色のRubyメソッド: `Module.class_exec`(翻訳)

Ruby: 「マジック」と呼ぶのをやめよう(翻訳)

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ