メタプログラミングで同じ形のアクセッサをまとめる

こんにちは、鈴木です。

今回はメタプログラミングの練習として、同じパターンを持つコードを改良していきます。

 

最初のコード

何かの会員サイトを作っているとします。

まずは会員クラスが必要となるので、以下のような Member クラスを定義しました。

会員の情報としては、「このサイトを初めて知ったメディア」と「会員の職業」を持ちます。

データベースには数値で保存したいので、それぞれ MEDIA と OCCUPATION という定数に、数値と文字列のマッピングを保持しています。

画面などには数値ではなく文字列で表示したいので、media_label と occupation_label というメソッドを定義しました。

動作を確認すると、以下のようになります。

 

同じパターンの部分をまとめる

最初のコードを眺めていると、同じパターンの部分があることに気付きます。

以下の部分がそうです。

属性値をキーとして、定数から値を取得しています。

この部分をまとめるために、次のメソッドを作成しました。

name には属性名(:media や :occupation)が渡されることを想定しています。

attr_label_reader の中では、define_method で name に「_label」を付けた名前のメソッドを定義しています。(例えば media_label や occupation_label)

定義したメソッドの中では、const_get で name を全て大文字にした定数を取得し、名前が name の属性値をキーとする値を取得します(例えば MEDIA[self.media] の値がメソッドの戻り値となります)。

まだ attr_label_reader を定義しただけなので、それを使うようにコードを修正します。

同じ形をしていた media_label と occupation_label は以下の 2 行に置き換えることができました。

 

まとめ

Rails にはかゆいところに手が届く多くの機能があります。

しかし、プロジェクト固有の「かゆいところ」は必ず出てきてしまいます。

そういったときに、Railsは機能不足だと嘆くのではなく、かといって同じパターンのコードを一生懸命書いてしまうのではなく、メタプログラミングで楽をするべきだと思います。

 

Comments are closed, but you can leave a trackback: Trackback URL.