なにが起こっているかを調べる方法を2つ示してみます。
1. print 文をいれて状況の変化を知る。
プログラムに次のように、状態を表示する行を追加して実行してみます。
z.rb
ruby
1num = gets.chomp.split(' ').map(&:to_i)
2
3while 1
4 flag = true
5 (0..num.size - 2).each do |i|
6 p i # これを追加
7 p num # これを追加
8 diff = num[i + 1] - num[i] # ←ここでエラー
9 if diff == 1 || diff == -1
10 num.delete_at(i + 1)
11 num.delete_at(i)
12 flag = false
13 end
14 end
15 break if flag == true
16end
17
18(0..num.size - 1).each do |i|
19 print num[i]
20end
走らせてみます。
$ ruby z.rb
1 2 3
0
[1, 2, 3]
1
[3]
z.rb:8:in `block in <main>': undefined method `-' for nil:NilClass (NoMethodError)
from z.rb:5:in `each'
from z.rb:5:in `<main>'
i = 1 になったとき、 num が [3] とサイズ1の配列になっていることがわかります。
この状態で num[1], num[2] にアクセスしようとすることになるので、エラーが発生しているのです。
2. デバッガで、エラーが起こったときブレークさせて、状況を調べる。
プログラムにつぎにように ブレークポイントを設定します。
ruby
1num = gets.chomp.split(' ').map(&:to_i)
2
3while 1
4 flag = true
5 (0..num.size - 2).each do |i|
6 binding.pry if num[ i + 1].nil? # これを追加
7 diff = num[i + 1] - num[i] # ←ここでエラー
8 if diff == 1 || diff == -1
9 num.delete_at(i + 1)
10 num.delete_at(i)
11 flag = false
12 end
13 end
14 break if flag == true
15end
16
17(0..num.size - 1).each do |i|
18 print num[i]
19end
走らせてみます。
$ ruby -r pry z.rb
1 2 3
From: /Users/katoy/zzz/zzz4/z.rb @ line 7 :
2:
3: while 1
4: flag = true
5: (0..num.size - 2).each do |i|
6: binding.pry if num[ i + 1].nil? # これを追加
=> 7: diff = num[i + 1] - num[i] # ←ここでエラー
8: if diff == 1 || diff == -1
9: num.delete_at(i + 1)
10: num.delete_at(i)
11: flag = false
12: end
[1] pry(main)> i
=> 1
[2] pry(main)> num
=> [3]
[3] pry(main)> num[i + 1] - num[i]
NoMethodError: undefined method `-' for nil:NilClass
from (pry):3:in `block in <main>'
[4] pry(main)> num[i + 1]
=> nil
↑では pry というデバッガをつかっています。
$ gem install pry とすることで、pry が利用可能になります。
pry については、 google で "ruby pry" などで検索すれば、たくさんの情報を得ることができます。