我有一个文本文件,我正在打开并从中创建对象。 它看起来像这样:
/home/music/Accident Murderer.mp3|4:37| Nas | Accident Murderer
/home/music/Bitch Bad.mp3 |4:49| Lupe Fiasco| Bitch Bad
/home/music/ITAL.mp3 |4:24| Lupe Fiasco| ITAL(Roses)
/home/music/The Coolest.mp3 |5:13| Lupe Fiasco| The Coolest
然后我使用以下代码创建歌曲对象:
songs = SongList.new
songFile = File.open('./songs.txt')
songFile.each do |line|
file, length, name, title = line.chomp.split(/\s*\|\s*/)
name.squeeze!(" ")
mins, secs = length.scan(/\d+/)
songs.append Karaoke::Song.new(title, name, mins.to_i*60+secs.to_i)
end
但是我收到以下错误消息:
songlist.rb:40:in `block in <class:SongList>': undefined method `squeeze!' for nil:NilClass (NoMethodError).
请有人帮忙。我不明白为什么'挤!'是一种未定义的方法。这是一个String类方法吗?
答案 0 :(得分:0)
您是否有空白处理线?也许在文件的最后?这将分为["",nil,nil,nil]
,因此name
将为nil
,这会导致您看到的错误。 。
对此的修复将如下所示:
songs = SongList.new
songFile = File.open('./songs.txt')
songFile.each do |line|
next if line.chomp.empty?
file, length, name, title = line.chomp.split(/\s*\|\s*/)
raise "Got less than four columns, line '#{line.chomp}'" if title == nil
name.squeeze!(" ")
mins, secs = length.scan(/\d+/)
songs.append Karaoke::Song.new(title, name, mins.to_i*60+secs.to_i)
end
next
应该跳过任何简单的空行,但你可以改变它以跳过你想要视为“在输入文件中确定,但不包含我的脚本数据”的任何内容。
我还添加了一个简单的验证,如果一行最初看起来没问题,但会意外地错过最后一列,会引发错误。我通常会推荐这种方法,至少在处理来自代码外部的数据的某个阶段,您应该检查它是否是您期望或需要的。
实际上可以跳过什么,输入文件中的错误取决于您。这个修改至少应该为你提供更多关于错误的线索。