Rails: クラスレベルの3つのアクセサを比較する(翻訳)

概要

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

Rails: クラスレベルの3つのアクセサを比較する(翻訳)

attr_accessorは、インスタンス変数のgetterとsetterを提供する非常に有用なマクロです。これと同じ効果をクラス変数でも得られれば、クラス変数でクラスを設定できて便利です。そのための方法として少なくともattr_accessorcattr_accessorclass_attributeの3つのアプローチがあります。継承を使わない場合はどれも同じに使えますが、継承がからむ場合の動作はかなり異なります。

1. attr_accessor: 値を継承したくない場合に使う

この場合は通常のattr_accessorを使いますが、ここではクラスレベルで使います。attr_accessorを使うと、各子クラスに変数が定義されますが、親クラスに設定された値は継承されません。各子クラスの属性の初期値はnilに設定されます。

class Parent
 class << self
   attr_accessor :foo
 end
end
class Child < Parent 
end
Parent.foo = 100
Child.foo #=> nil  // 値は継承されない
Child.foo = 200
Child.foo #=> 200
Parent.foo #=> 100 // 子クラスで値を変更しても親クラスの値には影響しない

訳注: attr_accessorはRubyのメソッドです。

2. cattr_accessor: 値をすべてのクラスで共有したい場合に使う

この場合はcattr_accessorで親クラスの値を子クラスに継承します。このとき、cattr_accessor宣言をclass << selfブロックの内側に置く必要はありません。ここで重要なのは、子クラスでクラス変数の値を再定義すると親クラスと子クラスの両方で値が変更されるという点です。

class Parent
  cattr_accessor :foo
end
class Child < Parent
end
class Grandchild < Child
end
Parent.foo = 100
Child.foo #=> 100
Child.foo = 200
Child.foo #=> 200
Parent.foo #=> 200     // 値は継承ツリーの上位に反映される
Grandchild.foo #=> 200 // 値は継承ツリーの下位に反映される

訳注: cattr_accessormattr_accessorのエイリアスです。

3. class_attribute: 継承した値を親クラスに影響を与えずに上書き可能にしたい場合に使う

私はこのシナリオが最も有用だと思います。class_attributeを使うと親クラスの変数値が継承され、継承した値は親クラスに影響することなく子クラスで安全に再定義できます。

class Parent
  class_attribute :foo
end
class Child < Parent
end
class Grandchild < Child
end
Parent.foo = 100
Child.foo #=> 100      // 値は継承される
Child.foo = 200 
Child.foo #=> 200
Parent.foo #=> 100     // 値を再定義しても親クラスには影響しない
Grandchild.foo #=> 200 // 再定義した値はその子クラスに継承される

関連記事

TestProf: Ruby/Railsの遅いテストを診断するgem(翻訳)

Rails: N+1クエリを「バッチング」で解決するBatchLoader gem(翻訳)

Rails: render_async gemでレンダリングを高速化(翻訳)

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833

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

hachi8833の書いた記事

BPSアドベントカレンダー

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ