Slide 1

Slide 1 text

Misokatsu.rb #1 Misokatsu.rb #1 Ruby 3.0 で変わった private と attr_xxx Ruby 3.0 で変わった private と attr_xxx

Slide 2

Slide 2 text

⾃⼰紹介 ⾃⼰紹介 名前:osyo Twitter : github : ブログ : 趣味で Ruby にパッチを投げたり気になった bugs.ruby のチケットを ブログにまとめたりしている Kaigi on Rails 銀座Rails Burikaigi2021 @pink_bangbi osyo-manga Secret Garden(Instrumental) ActiveRecord の歩み⽅ これからの Ruby と今の Ruby について 12 ⽉25 ⽇にリリースされる Ruby 3.0 に備えよう! Ruby 2.0 から Ruby 3.0 を駆け⾜で振り返る

Slide 3

Slide 3 text

Misokatsu.rb はワシが名付けたんじゃよ

Slide 4

Slide 4 text

今⽇話すこと 今⽇話すこと Ruby 3.0 で変わった private と attr_xxx Ruby 3.0 で変わった private と attr_xxx

Slide 5

Slide 5 text

public / private / protected のおさらい public / private / protected のおさらい public / private / protected はメソッドのアクセス参照を制御する機能 private にするとレシーバを付けてメソッドが呼べなくしたり等 class X # これは Ruby 3.0 で⼊ったエンドレスメソッド定義 def hoge = "hoge" # 引数の名前のメソッドを private 化する private :hoge # レシーバを付けない場合は呼び出せる def foo = hoge end # private 化されたメソッドはレシーバ付きで呼べない x = X.new p x.foo # error: private method `hoge' called for # (NoMethodError) x.hoge

Slide 6

Slide 6 text

Ruby 3.0 の public / private / protected について Ruby 3.0 の public / private / protected について Ruby 3.0 では private などの引数に配列を渡せるようになった 元々複数の引数を渡すこともできたが配列も渡せるようになった class X def hoge = "hoge" def foo = "foo" def bar = "bar" # 配列を渡して複数のメソッドを private 化できる # 以下のように可変⻑引数で書くことは以前からできてた # private :hoge, :foo, :bar private [:hoge, :foo, :bar] end pp X.private_instance_methods(false) # => [:hoge, :foo, :bar]

Slide 7

Slide 7 text

attr_accessor / attr_reader / attr_writer のおさらい attr_accessor / attr_reader / attr_writer のおさらい attr_accessor / attr_reader / attr_writer はアクセッサメソッドを定義 するメソッド class User # ゲッターメソッド #id メソッドが定義される attr_reader :id # セッターメソッド #name= メソッドが定義される attr_writer :name # アクセッサメソッド #age, #age= メソッドが定義される attr_accessor :age end homu = User.new homu.name = "homu" homu.age = 14 # これはエラーになる homu.id = 1

Slide 8

Slide 8 text

Ruby 3.0 の attr_accessor / attr_reader / attr_writer Ruby 3.0 の attr_accessor / attr_reader / attr_writer Ruby 3.0 では attr_accessor などの戻り値が『定義されたメソッドの 配列』を返すようになった class User # ゲッターメソッド名が返ってくる pp attr_reader :id, :status # => [:id, :status] # セッターメソッド名が返ってくる pp attr_writer :name # => [:name=] # ゲッターとセッターの両⽅のメソッドが返ってくる pp attr_accessor :age, :type # => [:age, :age=, :type, :type=] end

Slide 9

Slide 9 text

Ruby 3.0 で private と attr_accessor を Ruby 3.0 で private と attr_accessor を 組み合わせると… ? 組み合わせると… ?

Slide 10

Slide 10 text

private と attr_accessor を private と attr_accessor を ワンラインで適⽤できる ワンラインで適⽤できる

Slide 11

Slide 11 text

private attr_accessor :hoge, :foo と定義できる private attr_accessor :hoge, :foo と定義できる private は配列を受け取ることができる attr_accessor は配列を返す この2 つを組み合わせることでワンラインで完結することができる class User # attr_reader の結果を public 化する public attr_reader :id # attr_reader の結果を private 化する private attr_writer :name # attr_accessor すべてを private 化する private attr_accessor :age, :type end pp User.private_instance_methods(false) # => [:age, :name=, :type, :type=, :age=]

Slide 12

Slide 12 text

おまけ:クラスメソッドを private 化する おまけ:クラスメソッドを private 化する class スコープ内ではインスタンスメソッドを private 化する クラスメソッドを private 化する場合は特異クラスをオープンする class X # クラスメソッドを定義する def self.hoge = "hoge" # これはインスタンスメソッドを private 化するのでエラーになる private :hoge # 特異クラスをオープンしてその中で private 化する class <

Slide 13

Slide 13 text

以下のように attr_accessor も特異クラスのスコープで定義できる class X class < [:hoge, :foo, :foo=, :bar, :bar=, :hoge=, :initialize, :inherited]

Slide 14

Slide 14 text

まとめ まとめ

Slide 15

Slide 15 text

まとめ まとめ Ruby 3.0 から private の引数や attr_accessor の戻り値が少し変わった private はメソッド名を配列で受け取ることができるようになった attr_accessor は定義されたメソッド名を配列を返すようになった 少し変わっただけでめっちゃ便利に使えるようになった private + attr_accessor はかなり前から要望が来ていたのでやっと流 ⾏った機能 古くは 2012 年の頃からチケットが⽴っていた ⼀応⾮互換な変更ではあるので注意してね!!! [Feature #6198] public/protected/private with attr_*

Slide 16

Slide 16 text

参照 参照 [Feature #17314] Provide a way to declare visibility of attributes defined by attr* methods in a single expression

Slide 17

Slide 17 text

ご清聴 ご清聴 ありがとうございました ありがとうございました