メンバー変数やクラス変数のgetter/setterみたいなアクセッサーが
何個かあるみたいなのでまとめてみた。
準備
rubyのバージョンは2.3.0。
source 'https://rubygems.org'
gem 'rails', '5.1.1'
gem 'test-unit'
require 'test/unit'
extend Test::Unit::Assertions
require 'active_support/all'
module Mod
mattr_accessor :module_variable
self.module_variable = '<nil>'
thread_mattr_accessor :thread_module_variable
self.thread_module_variable = '<nil>'
end
class Base
include Mod
attr_accessor :instance_variable
cattr_accessor :class_variable
@@class_variable = '<nil>' # わかりやすいようにnilは文字列
thread_cattr_accessor :thread_class_variable
self.thread_class_variable = '<nil>'
def initialize
@instance_variable = '<nil>'
end
end
class Super < Base
self.thread_class_variable = '<nil>'
end
base = Base.new
sup = Super.new
attr_*系
インスタンス変数のアクセッサー。
base.instance_variable = 'madoka'
assert_equal base.instance_variable, 'madoka'
assert_equal sup.instance_variable, '<nil>'
cattr_*系
クラス変数用のアクセッサー。
base.class_variable = 'kaname'
assert_equal base.class_variable, 'kaname'
assert_equal sup.class_variable, 'kaname'
assert_equal Base.class_variable, 'kaname'
assert_equal Super.class_variable, 'kaname'
# 継承先で変更
sup.class_variable = 'homura'
assert_equal base.class_variable, 'homura'
assert_equal sup.class_variable, 'homura'
assert_equal Base.class_variable, 'homura'
assert_equal Super.class_variable, 'homura'
mattr_*系
モジュール用のアクセッサー。
alias :cattr_accessor :mattr_accessor
らしいです。
あと、こちらにも書かれてました。
便利だけど、値が変わったりするので気をつけて使いましょう。
Mod.module_variable = 'tomoe'
assert_equal Mod.module_variable, 'tomoe'
assert_equal base.module_variable, 'tomoe'
assert_equal sup.module_variable, 'tomoe'
# 継承先で変更
sup.module_variable = 'mami'
assert_equal Mod.module_variable, 'mami'
assert_equal base.module_variable, 'mami'
assert_equal sup.module_variable, 'mami'
# インスタンス作ったあとにモジュールくっつけてみる
class Other; end
other = Other.new
other.extend Mod
assert_equal other.module_variable, 'mami'
thread_(m|c)attr_*系
Threadに値がはいってるっぽい。
どこからでもアクセスできるグローバルな感じで使えそう。
継承先で値をかえても親の値は変わらないので、ちょっと安全な気がします。
(Threadにクラス名をキーにして値を格納してるっぽい)
Mod.thread_module_variable = 'sakura'
assert_equal Mod.thread_module_variable, 'sakura'
assert_equal base.thread_class_variable, '<nil>'
assert_equal sup.thread_class_variable, '<nil>'
# 継承元で設定
base.thread_class_variable = 'kyouko'
assert_equal Mod.thread_module_variable, 'sakura'
assert_equal base.thread_class_variable, 'kyouko'
assert_equal sup.thread_class_variable, '<nil>'
# 継承先で変更
sup.thread_class_variable = 'sayaka'
assert_equal Mod.thread_module_variable, 'sakura'
assert_equal base.thread_class_variable, 'kyouko'
assert_equal sup.thread_class_variable, 'sayaka'
p Thread.current.keys
# [:i18n_config, :"BigDecimal.precision_limit", :"BigDecimal.exception_mode", :attr_Mod_thread_module_variable, :attr_Base_thread_class_variable, :attr_Super_thread_class_variable]
まとめ
気がついたら、いろいろできてた。