Rubyのnilガードとは

ユーザーからの入力などで、名前や電話番号などが入っていた場合があるとする。
これらをたとえばDBに入れようとしても、nilだとエラーになってしまうかもしれない。

そんなときに、nilを防ぐための書き方がある。
これをnilガードという。

実際に例を見てみよう。

class Person
attr_accessor :last, :first
def fullname
@last ||= ""
puts "#{@last.upcase},#{@first}"
end
end
takashi = Person.new
takashi.first = "takashi"
takashi.last = "sato"
#=>「SATO,takashi」と表示される
takashi.fullname
takeshi = Person.new
takeshi.first = "世紀末リーダたけし"
#=>「,世紀末リーダたけし」と表示される
takeshi.fullname

この例では、

@last ||= ""

の部分で、nilガードを行っている。

@lastはnilなんだけど、upcaseを実行しても参照エラーにならない。
それは、ちゃんと@lastに””という空の文字列が入れられていたからだ。

この構文はちょっとわかりづらいけれど、

@last || (a = "")

と同じ意味だ。

その証拠に、fullnameメソッドを

def fullname
@last || @last = ""
puts "#{@last.upcase},#{@first}"
end

と変えても全く同じ結果になる。

「||」演算子は、被演算子のいずれかがtrueであれば、trueを返す。
そして、nilとfalse以外は全てtrueになるのが||演算子の特徴でもある。

つまり、最初の@lastの部分で、@lastがnilであるかどうか判定している。
そいで、nilであった場合は、1番目の判定(左側の判定)でfalseになって、
2番目の判定(右側)を行う。

そこで、@lastに””(空文字)を代入するという処理を行っている。

if文にするとこうなる。

  def fullname
if @last != nil
@last = @last
else
@last = ""
end
puts "#{@last.upcase},#{@first}"
end

上のif文は、nilブロック構文と同じ意味だ。

最後に、2番目の演算をfalseにすると・・・

def fullname
@last ||= false
puts "#{@last.upcase},#{@first}"
end

upcaseでエラーが発生する。

tmp2.rb:8:in `fullname': undefined method `upcase' for false:FalseClass (NoMeth
dError)
from tmp2.rb:24:in `<main>'

メタプログラミングRuby

メタプログラミングRuby

メタプログラミング Rubyの付録、p.268に書いてあった。
こういうtipsは「知ってるか知らないか」で違いが出る部分なので、しっかり押さえておきたいと思った。
本を読むまで知らなかったもん。



お金があるかないかで人生の楽しさは全く変わってきます。

お金があっても幸せになれるとは限りませんが、お金がない人生は不幸です。

お金がなかった私が、転職して年収1000万を超えるまでにお世話になったブログを紹介します。

エンジニア転職のリアル

今の時代は、お金を稼げるかどうかは能力の有無よりも触れた情報の質によるものが大きいです。
ぜひ皆さんも良質な情報に触れて、お金持ちになって人生を充実させてください。