RubyとRailsを使っていて、覚えたnilに関するまとめ

nilや例外に関する備忘録。
下記の記載はrails consoleで確認。

ActiveRecord 関連

「例外が発生する」パターンと「IDが見つからなければnilを返す」パターンを使い分ける必要がある。

  • find
User.find(1)
# => #<User id: 1, name: "sinsoku">
User.find(999) # 存在しないid
# 例外 ActiveRecord::RecordNotFound: Couldn't find User with ID=999
  • find_by_id
User.find_by_id(1)
# => #<User id: 1, name: "sinsoku">
User.find(999) # 存在しないid
# => nil
  • where
User.where(:id => 1).first
# => #<User id: 1, name: "sinsoku">
User.where(:id => 999).first # 存在しないid
# => nil

Rubyのif文

if文の中に代入があれば、if文の条件式の結果に関係なく、変数はnilで初期化される。

  • trueだとfooに値が入る
if true
  foo = 1
end
foo
# => 1
  • falseだとbarはnilになる
if false
  bar = 2
end
bar
# => nil

変数の未定義による例外(NameError: undefined local variable...)は発生しない

後置のif文も同じ動作をする

  • 後置のif
fizz = true if true
# => true
buzz = true if false
# => nil

nil?, empty?, present?

nil.nil?
# => true
  • empty?
nil.empty?
# 例外 NoMethodError: You have a nil object when you didn't expect it!
"".empty?
# => true
[].empty?
# => true
{}.empty?
# => true
0.empty?
# 例外 NoMethodError: undefined method `empty?` for 0:Fixnum
  • present?
nil.present?
# => false
[].present?
# => false
{}.present?
# => false
0.present?
# => true

配列やハッシュに中身があると、present?はtrueを返すため、
下記のような配列の場合、compactする必要がある。

[nil].present?
# => true
[nil].compact.present?
# => false