Reputation: 774
Beginner here, teaching myself Ruby. I'm getting Errno::ENOENT and I think I figured out how, but I don't understand why I'm getting it. Here's the error:
Downloading 4 files: . . . c11-photos.rb:29:in `rename': No such file or
directory - (c:/users/7/dropbox/3-coding/ruby/study/blizz-01.jpg, blitz-03.jpg)
(Errno::ENOENT)
from c11-photos.rb:29:in `block in <main>'
from c11-photos.rb:20:in `each'
from c11-photos.rb:20:in `<main>'
First, the program works. All files are accurately moved and renamed. But this error pops up after it's done running. For this particular job, there were only 2 pictures to be moved to a new directory, but notice that the program says it downloaded 4 files. What seems to be happening is that my #each
method is somehow repeating itself when executed. It's trying to continue moving files even when the target directory has no more picture files to move. I'm guessing this because the "blizz-01.jpg" file is one of the files to be moved, but the "blitz-03.jpg" isn't the name of any file (this is the would-be name if there was a third picture to move). Since "blizz-01.jpg" has already been moved, this would make it give me a "No such file ..." error. Of course, I don't really know if this is what's happening, but that seems to be what the error says.
Why am I getting this error and/or what's wrong with my code that it's producing this problem?
Here's my code:
require "yaml"
puts "Where to move the pictures?"
destination = gets.chomp
Dir.chdir "#{destination}"
puts "What shall we name this batch?"
batch = gets.chomp
puts "Where to get your new pictures?"
findpics = gets.chomp
pictures = Dir["#{findpics}/*.{jpg,JPG,JPEG,jpeg,png,PNG}"]
print "Downloading #{pictures.length} files: "
amount = 1
pictures.each do |pic|
print ' . '
newname = if amount < 10
"#{batch}-0#{amount}.jpg"
else
"#{batch}-#{amount}.jpg"
end
File.rename pic, newname
amount += 1
end
puts
puts "Operation complete!"
Thank you your help!
Upvotes: 1
Views: 564
Reputation: 58741
Case-insensitive filesystem?
blizz-01.jpg
is matched twice, once by "#{findpics}/*.jpg"
and once by "#{findpics}/*.JPG"
, which are two of the expansions of your filesystem glob argument to Dir[]
. Same remark for the other file. Obviously, the second time it's processed in your each
loop, it's already been renamed.
If you want this to work both on case-sensitive and case-insensitive filesystems, and permit ".jpg" and ".JPG" and so on, you can quickly and simply unique-ify the matches:
pictures = Dir["#{findpics}/*.{jpg,JPG,JPEG,jpeg,png,PNG}"].uniq
Upvotes: 4