LoginSignup
3
4

More than 5 years have passed since last update.

ruby/railsのaccessorいろいろ

Last updated at Posted at 2017-05-19

メンバー変数やクラス変数の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]

まとめ

気がついたら、いろいろできてた。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4