日々徒然

プログラミングしたりお酒飲んだりする毎日

RubyGold対策①

はじめに

下半期の目標で『RubyGold取得』を掲げているものの、11月末まで全然勉強できなかった(しなかった)ので、これから本腰入れて勉強開始しようと思います。

Rubyの実行環境

分かりやすくまとまってるサイト

Ruby Gold対策(実行環境) - 気軽に楽しくプログラムと遊ぶ

多重代入

なんとなく分かっていたけど、右辺に*がつくパターンってどんな動きだっけ?ってなった

るりましっかり読もう

docs.ruby-lang.org

irb(main):001:0> x,y = [1,2,3]
irb(main):002:0> x
=> 1
irb(main):003:0> y
=> 2
irb(main):004:0> x,*y = [1,2,3]
irb(main):005:0> x
=> 1
irb(main):006:0> y
=> [2, 3]
irb(main):007:0> x,*y = *[1,2,3]
irb(main):008:0> x
=> 1
irb(main):009:0> y
=> [2, 3]
irb(main):010:0> x,y = *[1,2,3]
irb(main):011:0> x
=> 1
irb(main):012:0> y
=> 2

Rational

初見でした。

IntとRationalの計算はRational,FloatとRationalの計算はFloatになるみたい。

irb(main):029:0> 4/5r
=> (4/5)
irb(main):030:0> 4.0/5r
=> 0.8
irb(main):031:0> 

ブロック

ブロック引数を{}で囲むときには()省略不可、do~endならOK

throw/catch

これも初見。

raise/rescueっぽい感じがする。

irb(main):053:1* def puts_hoge
irb(main):054:1*   puts "catch前"
irb(main):055:1*   throw :exit
irb(main):056:1*   puts "hoge"
irb(main):057:0> end
=> :puts_hoge
irb(main):058:0* catch :exit do
irb(main):059:0* puts_hoge
irb(main):060:-> end
catch前
=> nil # hogeが出力されない

返り値はthrowに渡されたオブジェクトっぽい

Kernel.#throw (Ruby 3.0.0 リファレンスマニュアル)

super

()付きと無しで違いあり。

docs.ruby-lang.org

いままでそこまで意識して使ってなかった...

たしかにassign_attributesをオーバーライドする時とかsuperだけ書いてる...

public, private, protectedの違い

この辺り実は全然気にしてなかった

特にRailsを書いてる時は「このメソッドは外から呼び出す必要ないからprivateで良いか〜」ぐらいの認識。

伊藤さんのこのブログが分かりやすかった↓

JavaやC#の常識が通用しないRubyのprivateメソッド - give IT a try

自分でも動かしてみた

class Hoge
  protected

  def hoge_protected
    puts "protectedです〜"
  end

  private

  def hoge_private
    puts "privateです〜"
  end
end

class Piyo < Hoge
  def call
    hoge_protected # サブクラス内から呼び出せる
    hoge_private # サブクラス内から呼び出せる
    Piyo.new.hoge_protected # サブクラス内でサブクラスのインスタンスから呼び出せる
  end

  def call_with_reciever
    Hoge.new.hoge_protected # サブクラス内で自身のインスタンスから呼び出せる
    Hoge.new.hoge_private # レシーバー付けたらもちろんエラー
  end
end

class Hogepiyo
  def call_hoge
    Hoge.new.hoge_protected # サブクラスじゃないと呼べない
  end

  def call_piyo
    Piyo.new.hoge_protected # サブクラスじゃないと呼べない
  end
end

privateをサブクラスから呼び出せるのは知らなかった...

piyo.callだとPiyoクラスがselfになるから、メソッド探索の時にsuperクラスのhoge_privateを見つけて呼び出してる感じなのかな?

protectedselfが自分自身orサブクラスのインスタンスでも呼び出せる。

どっちもサブクラス内で呼べるけど、レシーバーを付けるときはprotectedみたいな感じで覚えとけばとりあえず混乱しなさそう。

ちなみにオーバーライドできるから要注意

class Hoge
  protected

  def hoge_protected
    puts "protectedです〜"
  end

  private

  def hoge_private
    puts "privateです〜"
  end
end

class Piyo < Hoge
  def call
    hoge_protected # オーバーライドされる
    hoge_private # オーバーライドされる
    Piyo.new.hoge_protected # オーバーライドされる
  end

  def call_with_reciever
    Hoge.new.hoge_protected # オーバーライドされない
  end

  protected

  def hoge_protected
    puts "オーバーライド後のprotectedです〜"
  end

  private

  def hoge_private
    puts "オーバーライド後のprivateです〜"
  end
end

感想

privateprotectedに関しては、まだ理解が浅い感じがする...