プロを目指す人のためのRuby入門・第5章重要ポイントまとめ

「プロを目指す人のためのRuby入門」の第5章を読み終わりました

個人的に重要と判断したポイントをまとめます。

同じシンボルは同じオブジェクト
#同じ文字列でもそれぞれ違うオブジェクト
irb(main):001:0> 'apple'.object_id
=> 70368539041060
irb(main):002:0> 'apple'.object_id
=> 70368539033900
irb(main):003:0> 'apple'.object_id
=> 70368539005880

#同じシンボルは同じオブジェクト
irb(main):004:0> :apple.object_id
=> 1162588
irb(main):005:0> :apple.object_id
=> 1162588
irb(main):006:0> :apple.object_id
=> 1162588

同じシンボルは同じオブジェクトということは、シンボルに対して破壊的に変更を加えた際の他のオブジェクトへの影響があるかと思いきや…

#Symbolクラスにupcase!メソッドは定義されていない
irb(main):007:0> :apple.upcase!
NoMethodError: undefined method `upcase!' for :apple:Symbol
Did you mean?  upcase

シンボルはイミュータブルはオブジェクトであるため、そもそも破壊的に変更されないことが分かりました。

キーワード引数

キーワード引数はハッシュの形で作成する

def order_burger_set(menu, drink: true, potato: true)
  if menu
    puts "#{menu}バーガーセットを注文します"
  end

  if drink
    puts 'セットで飲み物を注文します '
  end

  if potato 
    puts 'セットでポテトを注文します'
  end
end

上のメソッドを実行すると

order_burger_set( 'フィッシュ', drink: true, potato: false )
#=> 
フィッシュバーガーセットを注文します
セットで飲み物を注文します

potato: falseがちゃんと反映されています
また、キーワード引数をメソッド呼び出し時に省略すると

order_burder_set( 'フィッシュ')
#=>
フィッシュバーガーセットを注文します
セットで飲み物を注文します
セットでポテトを注文します

メソッド定義時にデフォルト値として指定した値が適用されました
今度は、デフォルト値を持たないメソッドを定義してみます

def order_burger_set(menu, drink: , potato: )
  # 省略
end

上で定義したメソッドに引数を入れて呼び出すと

order_buy_burger( 'チーズ', drink: false, potato: true)
#=>
チーズバーガーセットを注文します
セットでポテトを注文します

メソッドを呼び出すことができました。
しかし、メソッド呼び出しの際、デフォルト値を省略すると

order_buy_burger( 'チーズ', drink: , potato: )
#=> ArgumentError: missing keywords: drink,potato

メソッドを呼び出すことができませんでした。

これらより、分かったことを以下にまとめます

1.キーワード引数はハッシュの形で作成する
2.キーワード引数にはデフォルト値を設定することができる
3.デフォルト値が設定されているキーワード引数は、メソッド呼び出しの際省略することができる
4.デフォルト値が設定されていないキーワード引数は、メソッド呼び出しの際省略することができない
||=を使った自己代入
limit ||= 10

このコードは、
「limitがnilまたはfalse(つまり偽)であれば右辺の10を代入し、それ以外(つまり真)であれば、limitの値をそのまま使う」という意味。
分かりやすく考えると

 n += 1  
 #=> n = n + 1
 
#同じように展開すると
limit ||= 10  
#=> limit = limit || 10 

ここで、論理演算子||は、式全体の真偽値が確定した時点で評価を終了し、そのときの値を戻り値として返すため、

limit = nil

limit ||= 10
↓
limit = limit || 10

#limitにはnilが代入されているので、論理演算子||は10までを評価したうえで真偽値を確定し最後に評価した10を返している
limit = 100

limit ||= 10
↓
limit = limit || 100

#limitには100が代入されているので、論理演算子||は左側のlimitを評価した時点で真偽値を確定させ、最後に評価したlimit(100)を返しています

感想
シンボルが内部的に整数だとは知りませんでした…!
同じシンボルは同じオブジェクトだからメモリの使用効率が良い -> 
オブジェクトが変更されたら全部影響を受けてしまって困りそう… ->
シンボルはイミュータブルなので心配なし!
という流れにめちゃくちゃ感動しました(しょうもなすぎて笑われそうですが…笑)
シンボル最高 ~