クラスの属性は、クラスの特異クラスでattr_xxxxx
やりたいこと
- クラスごとに値をもたせたい
- サブクラスやスーパークラスに共有したくない
こういうとき、クラスのインスタンス変数を使うわけですが、attr_accessor
みたいにクラスマクロ的なの使ってわかりやすくしたいです。
答え
クラスの特異クラスでattr_accessor
class MyClass class << self attr_accessor :attr1 end end class HogeClass class << self attr_accessor :attr2 end end class SubMyClass < MyClass class << self attr_accessor :attr3 end end MyClass.attr1 = 'hoge' p MyClass.attr1 # => "hoge" p SubMyClass.attr1 # => nil # p HogeClass.attr1 # => undefined method `attr1' for HogeClass:Class (NoMethodError) SubMyClass.attr3 = 'fuga' p SubMyClass.attr3 # => "fuga" # p MyClass.attr3 # => undefined method `attr3' for MyClass:Class (NoMethodError)
スレッド
threads = [] t = Thread.new do Thread.pass MyClass.attr1 = 'hoge' sleep 2 p MyClass.attr1 # => "hoge" end threads.push(t) t = Thread.new do Thread.pass sleep 1 p MyClass.attr1 # => "hoge" MyClass.attr1 = "fuga" end threads.push(t) threads.each(&:join)
実行結果
C:\Ruby22-x64\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) C:/Users/Yuichi/IdeaProjects/metaprogrammingruby/example/class_attributes.rb "hoge" "fuga"
当然ながらスレッドセーフではないので、認識した上で上手く使いましょう。
このあたりのことはメタプログラミングRubyが大変わかりやすいです。おすすめ。
- 作者: Paolo Perrotta,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/10/10
- メディア: 大型本
- この商品を含むブログ (1件) を見る