无法使用Ruby foreach或glob与ARGV一起工作......或者根本不能

时间:2015-02-13 18:04:15

标签: ruby foreach glob directory taglib-ruby

我使用taglib-ruby来查看每天可以听多少次歌曲。我让它为单首歌曲工作,但现在我试图修复它,这样它就可以遍历一个目录并吐出每首歌的长度以及每天可以听多少次。它运行时不会抛出错误,但它也不会输出任何内容。我不认为它出于某种原因看到了这些文件。我试图使用foreach并不断收到错误说:

$ ruby songtime.rb /media/ab/storage/Music/Between\ the\ Buried\ and\ Me/[2007]\ Colors/
songtime.rb:9:in `block (2 levels) in <main>': undefined method `length' for nil:NilClass (NoMethodError)
        from /home/ab/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/gems/taglib-ruby-0.7.0/lib/taglib/base.rb:8:in `open'
        from songtime.rb:7:in `block in <main>'
        from songtime.rb:4:in `foreach'
        from songtime.rb:4:in `<main>'

如果我只是将目录名称硬编码到程序中,就会发生同样的问题,例如:

#!/usr/bin/ruby
require "taglib"

Dir.foreach(ARGV[0]) do |songfile|

  next if songfile == '.' or songfile == '..'
  TagLib::FileRef.open(songfile) do |mp3|
    properties = mp3.audio_properties
    songLength = properties.length
    puts "Song length is #{songLength}"
    puts "You can listen to this song #{(24*60*60/songLength * 1000).floor / 1000.0} times per day."
  end

end

所以我尝试切换到glob:

#!/usr/bin/ruby
require "taglib"

Dir.glob("#{ARGV[0]}*.mp3") do |songfile|

  TagLib::FileRef.open(songfile) do |mp3|
    properties = mp3.audio_properties
    songLength = properties.length
    puts "Song length is #{songLength}"
    puts "You can listen to this song #{(24*60*60/songLength * 1000).floor / 1000.0} times per day."
  end

end

哪个不起作用。没有错误消息,但没有打印任何内容。如果我放

,它也不起作用
#!/usr/bin/ruby
require "taglib"

Dir.glob("/media/ab/storage/Music/Between the Buried and Me/[2007] Colors/*.mp3") do |songfile|

  TagLib::FileRef.open(songfile) do |mp3|
    properties = mp3.audio_properties
    songLength = properties.length
    puts "Song length is #{songLength}"
    puts "You can listen to this song #{24*60*60/songLength} times per day."
  end

end
这是什么意思?对不起是一个菜鸟新手。

2 个答案:

答案 0 :(得分:0)

Dir会自动从程序本身所在的路径开始...所以当我做/ media / ab ...等时它实际上是在执行Code / Ruby / ab / media等(这不是不存在。。

我改变了程序,这是工作版本。

#!/usr/bin/ruby
require "taglib"
Dir.chdir(ARGV[0])
Dir.foreach(Dir.pwd) do |songfile|

  next if songfile == '.' or songfile == '..' or songfile !~ /[\s\S]*.mp3/
  puts songfile
  TagLib::FileRef.open(songfile) do |mp3|
    properties = mp3.audio_properties
    songLength = properties.length
    puts "Song length is #{songLength}"
    puts "You can listen to this song #{24*60*60/songLength} times per day."
    puts ""
  end

end

答案 1 :(得分:-1)

夫妻俩。

1)Dir.glob想要一个类似于shell上使用的glob字符串。例如Dir.glob("*.mp3")或子目录Dir.glob("**/*.mp3")

2)你实际上并没有在上一个例子中调用循环。循环遍历数组(您正在进行)时,需要使用'each'方法。

Dir.glob("*.mp3").each do |filename|
 ... 
end

否则,您将块(do和end之间的代码)传递给方法,而不是传递给循环方法each

查看:http://ruby-doc.org//core-2.2.0/Array.html了解可以应用于数组的各种方法。