Search code examples
rubyforeachglobdirectorytaglib-ruby

Can't get Ruby foreach or glob to work with ARGV... or at all


I'm using taglib-ruby to see how many times you can listen to a song per day. I got it to work for single songs, but now I'm trying to do fix it so it can loop through a directory and spit out how long each song is and how many times per day you can listen to it. It doesn't throw an error when it runs, but it also doesn't output anything. I don't think its seeing the files for some reason. I tried to use foreach and kept getting an error saying this:

$ 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>'

Same problem would occur if I just hardcoded the directory name into the program, which was something like:

#!/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

So I tried switching to 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

Which doesn't work. There are no error messages, but nothing gets printed. It also doesn't work if I put

#!/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

Sup with this? Sorry for being a noob rookie.


Solution

  • Dir is automatically going to have it start from the path where the program itself is located... so when I did /media/ab... etc it was actually doing Code/Ruby/ab/media etc (which doesn't exist).

    I changed the program and here's the working version.

    #!/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