0

我有一个文本文件,我正在打开并从中创建对象。它看起来像这样:

/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).

有人可以帮忙吗。我不明白为什么要“挤”!是一个未定义的方法。这是一个字符串类方法对吗?

4

1 回答 1

1

您是否有可能正在处理一个空白行?也许在文件的末尾?那会分裂成["",nil,nil,nil], sonamenil导致你看到的错误。. .

对此的修复将如下所示:

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空行,但您可以更改它以跳过任何您想视为“在输入文件中正常,但不包含我的脚本的数据”的内容。

我还添加了一个简单的验证,如果一行最初看起来不错,但会意外丢失最后一列,则会引发错误。我通常会推荐这种方法,至少在处理来自代码外部的数据的某个阶段,您应该检查它是否真的是您期望或需要的。

什么是可以跳过的,什么是输入文件中的错误取决于您。这种修改至少应该给你一些关于哪里出了问题的更多线索。

于 2013-04-14T19:51:36.273 回答