Category Archives: 仕分け中

紅玉のニル


アニメ『ニル・アドミラリの天秤』

作画ってあまり気にしたことがないのですが、実に綺麗だなあと思います。逆ハーレムは大好物なので、いつも溜め込んでから一気に見ます。原作はPS VITA向けのゲームのようで、アニメを全部みた後、きっとプレイしてしまうことでしょう。

ニル・アドミラリ(Nil admirari)は、 何事にも驚かない意味のラテン語らしいのですが、この綴りに既視感。なるほどどこかで見たことあるなあと思ったら、Rubyを使ってると出てくるキーワード、nilではないですか。英辞書で調べると、nilはゼロって意味なのですが、Rubyではゼロの意味で使うわけではないようです。

irbで確認してみます。

文字列を表示してくれるp、何も文字列を与えずに実行すると、nilが返ります。

takk@deb9:~/tmp$ irb
irb(main):001:0> p "Hello"
"Hello"
=> "Hello"
irb(main):002:0> p
=> nil
irb(main):003:0>

数値の計算でゼロになる場合は、nilは返りません。

irb(main):001:0> 10 - 10
=> 0
irb(main):002:0>

計算を優先させる括弧をつけても、nilでなく0が返ります。

irb(main):001:0> (2 - 2)
=> 0
irb(main):002:0> 

ところが、括弧の中に計算式がないと、nilが返ります。

irb(main):002:0> ()
=> nil
irb(main):003:0>

何もないからnilなんですね。

次に、定義していない変数aを、表示するとどうなるか。

irb(main):001:0> p a
NameError: undefined local variable or method `a' for main:Object
        from (irb):1
        from /usr/bin/irb:11:in `<main>'
irb(main):002:0>

nilが返るのではなく、エラーが返りました。えっ、どうして!?
まあ、そういうものと覚えてしまうことにしました。

次は配列。配列の引き算でnilが返るでしょうか。

irb(main):001:0> [1,2,3]
=> [1, 2, 3]
irb(main):002:0> [1,2,3] - [1,2,3]
=> []
irb(main):003:0>

空の配列が返りました。入れ物は引き算してくれないのですね。まあ、入れ物まで消えてしまうと、使い勝手が悪くなりそうですが。

次は、元々空の配列だった場合の引き算。やはり空の配列が返るだけです。

irb(main):001:0> [] - []
=> []
irb(main):002:0>

次は、配列のメソッドでnilが返るか試してみます。。
配列の最初の要素を取得するメソッド、firstを実行してみます。

irb(main):001:0> [1,2,3].first
=> 1
irb(main):002:0>

配列に最初の要素が返りました。

配列が空の場合はどうでしょうか。

irb(main):002:0> [].first
=> nil
irb(main):003:0>

nilが返りました。だんだん分かってきた気がします。

firstと変わりませんが、shiftでも試してみます。

irb(main):002:0> [].shift
=> nil
irb(main):003:0>

nilが返りますね。

次は、ランダムに要素を取得するメソッド、sample。

irb(main):001:0> [1,2,3].sample
=> 2
irb(main):002:0> [1,2,3].sample
=> 1
irb(main):003:0> [].sample
=> nil
irb(main):004:0>

配列が空の場合に、nilが返りました。

次はgrep。パターンにマッチする要素がある場合は、その要素が返ります。

irb(main):001:0> ["abc","def","ghi"].grep(/f$/)
=> ["def"]
irb(main):002:0>

マッチするものがない場合は、

irb(main):003:0> ["abc","def","ghi"].grep(/k/)
=> []
irb(main):004:0>

空の配列が返りました。nilが返るかなあと思ってたのですが、これも使い勝手を考えると、空の配列が都合良さそうです。

次はfind。条件を満たす要素を探します。

irb(main):001:0> [1,2,3].find{|a| a == 2}
=> 2
irb(main):002:0>

条件に合うものが見つからないと、

takk@deb9:~/tmp$ irb
irb(main):001:0> [1,2,3].find{|a| a == 5}
=> nil
irb(main):002:0>

nilが返りました。ん~、grepの時は空の配列だったのに、findで見つからないとnilというのは、何故でしょう。まあ、学習していけばそのうち分かるでしょう。

次は変数に代入して、classを確認。

irb(main):001:0> a=1
=> 1
irb(main):002:0> a.class
=> Fixnum
irb(main):003:0>

nilを代入してclassを確認。

irb(main):002:0> a=nil
=> nil
irb(main):003:0> a.class
=> NilClass
irb(main):004:0>

なるほど。

object_idを取得。

irb(main):004:0> a.object_id
=> 8
irb(main):005:0>

nilもオブジェクトなのですね。不思議です。

次はif文の中を通る場合と通らない場合。

irb(main):001:0> a=1
=> 1
irb(main):002:0> if a==1
irb(main):003:1>  p "HELLO"
irb(main):004:1> end
"HELLO"
=> "HELLO"
irb(main):005:0> if a==2
irb(main):006:1>  p "HELLO"
irb(main):007:1> end
=> nil
irb(main):008:0>

通る場合は、nilが返りませんでしたが、pを使ってるからかもしれません。
if文の中を空にして確認してみます。

irb(main):001:0> a=1
=> 1
irb(main):002:0> if a==1
irb(main):003:1> end
=> nil
irb(main):004:0>

つまり何も処理がないとnilなんですね。

ちょっと難しいところがあるので、まだまだ学習が必要です。