Не могу заставить Ruby foreach или glob работать с ARGV... или вообще

Я использую 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 ответа

Решение

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) Dir.glob хочет строку glob, похожую на ту, что используется в оболочке. что-то вроде Dir.glob("*.mp3") или для подкаталогов Dir.glob("**/*.mp3"),

2) вы на самом деле не вызываете цикл в вашем последнем примере. При циклическом просмотре массива (который вы делаете) вам нужно использовать метод "каждый".

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

В противном случае вы передаете блок (код между do и end) методу, а не методам цикла each,

Проверьте: http://ruby-doc.org//core-2.2.0/Array.html для отдельных методов, которые вы можете применить к массиву.

Другие вопросы по тегам