Не могу заставить 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 для отдельных методов, которые вы можете применить к массиву.