Learning ruby by the cherry book! (Chapter 5: Hash & Symbol)
Ruby Programming
プログラミング言語の再学習としてプロを目指す人のためのRuby入門[改訂2版]を読み始めましたので、気になる点をまとめます。
5.2.2 ハッシュの繰り返し処理
currencies = { 'japan' => 'yen', 'us' => 'dollar', 'india' => 'ruppe' }
currencies.each do |k, v|
puts "#{k}: #{v}"
end
currencies.each do |k_v|
puts "#{k_v[0]}: #{k_v[1]}"
end
# どちらもおなじ
# japan: yen
# us: dollar
# india: ruppe
5.2.3 ハッシュの比較・要素数の取得・要素の削除
# 比較
a = {'x' => 1, 'y' => 2}
b = {'x' => 1, 'y' => 2}
# 同じ値ならtrue
a == b #=> true
c = {'y' => 2, 'x' => 1}
# 並び順が違ってもtrue
a == c #=> true
d = {'y' => 2, 'x' => 10}
# valueが異なるとfalse
a == d #=> false
# 削除
a.delete('x') #=> 1
a #=> {"y"=>2}
5.3.1 シンボルと文字列の違い
# Classが違う
:apple.class #=> Symbol
'apple'.class #=> String
# シンボルのほうが比較が高速
## 同じシンボルは同じオブジェクト、同じ文字列は、異なるオブジェクトになる
## そのためシンボルのほうがメモリの使用効率がよい。
:apple.object_id #=> 1515868
:apple.object_id #=> 1515868
:apple.object_id #=> 1515868
'apple'.object_id #=> 70154894261080
'apple'.object_id #=> 70154894255260
'apple'.object_id #=> 70154894274160
### メモ: Interger型も同じ数値は同じオブジェクト指す
1.class #=> Integer
1.object_id #=> 3
1.object_id #=> 3
1.object_id #=> 3
# シンボルは破壊てきな操作ができない
## 値を変更させたくない場合に有効
ハッシュのキーに使うと文字列よりも高速に値を取り出すことができる
case文の条件に使う場合も処理効率がいい
status = :done
case status
when :todo
# 処理
when :doing
# 処理
when :done
# 処理
end
5.5 convert_lengthの実装
nk-ty.github.io/sample/ruby-book at main · nk-ty/nk-ty.github.io
5.6.2 **でハッシュを展開させる
h = { us: 'dollar', india: 'rupee' }
{ japan: 'yen', **h } #=> { japan: 'yen', us: 'dollar', india: 'rupee' }
# 上と同じ
{ japan: 'yen' }.merge(h)
5.6.9 ハッシュのデフォルト値
h = {}
h[:foo] #=> nil
h = Hash.new('hello')
h[:foo] #=> 'hello'
h = Hash.new('hello') #=> {}
h #=> {}
h[:hoge] #=> "hello"
a = h[:hoge] #=> "hello"
b = h[:bar] #=> "hello"
# 毎回同じオブジェクトが代入される
a.object_id #=> 70335178448700
b.object_id #=> 70335178448700
a.equal?(b) #=> true
# 破壊的な変更を行うと影響がある
a.upcase! #=> "HELLO"
a #=> "HELLO"
b #=> "HELLO"
# ブロックでデフォルト値を定義
h = Hash.new { 'hello' }
h = Hash.new { 'hello' } #=> {}
a = h[:fuga] #=> "hello"
b = h[:fuga] #=> "hello"
# 異なるオブジェクトを返す
a.object_id #=> 70335177821840
b.object_id #=> 70335177871540
# 破壊的変更を加えても影響なし
a.upcase! #=> "HELLO"
b #=> "hello"
&.演算子(ぼっち演算子)
nil対策になる。
レシーバーがnilの場合にメソッドを呼び出すとNoMethodErrorになるが、&.演算子を使うとnil
を返すので、エラーにならない
nil.upcase #=> NoMethodError (undefined method `upcase' for nil:NilClass)
nil&.upcase # => nil