I'm trying to simply lower-case all of the files in a directory. It
doesn't work because RUBY complains about not being able to convert
"nil" to a string. Why in the world is it even including "nil" in my
array?
files = Dir.glob('*.pdf')
files.each do |file|
File.rename(file, file.downcase!)
end
It says:
"...can't convert nil into String (Type error)..."
I think you're mistaking the source of your error here. Check this out
(ri String#downcase!):
Downcases the contents of _str_, returning +nil+ if no changes were
made.
So you're call to +downcase!+ is returning nil in the cases where
+file+ was already downcased. When +File.rename+ sees that nil and
tries to convert it to a String, it raises the error you see.
Try using +String#downcase+ instead (note the lack of the exclamation point).
Jacob Fugal
···
On 6/22/06, Peter Bailey <pbailey@bna.com> wrote:
I'm trying to simply lower-case all of the files in a directory. It
doesn't work because RUBY complains about not being able to convert
"nil" to a string. Why in the world is it even including "nil" in my
array?
files = Dir.glob('*.pdf')
files.each do |file|
File.rename(file, file.downcase!)
end
It says:
"...can't convert nil into String (Type error)..."
An excellent illustration of why side-effects can be harmful.
file.downcase! has to be evaluated before File.rename can be evaluated. #downcase! returns nil if no changes are made, so for any file that's already in lower case, you're making this call:
File.rename(file, nil)
You can fix this if you change the ! method to the normal #downcase. This will also help you avoid a more subtle bug:
files = Dir.glob('Test')
=> ["Test"]
files.each do |file|
File.rename(file, file.downcase!)
end
files = Dir.glob('Test')
=> ["Test"] # What the hell? shouldn't that be gone?
It's the same bug biting you in a different way: this time, because #downcase! is evaluated before the call to #rename, it's modifying the file variable in-place, so #rename is effectively being called like this:
File.rename('test', 'test')
Where 'test' obviously doesn't exist in the first place (or even if it did, it's still not what you wanted).
matthew smillie.
···
On Jun 22, 2006, at 19:22, Peter Bailey wrote:
I'm trying to simply lower-case all of the files in a directory. It
doesn't work because RUBY complains about not being able to convert
"nil" to a string. Why in the world is it even including "nil" in my
array?
files = Dir.glob('*.pdf')
files.each do |file|
File.rename(file, file.downcase!)
end
I had no idea that Ruby evaluated it that way. Thank you for this
detailed explanation.
Pat
···
On 6/22/06, Matthew Smillie <M.B.Smillie@sms.ed.ac.uk> wrote:
It's the same bug biting you in a different way: this time, because #downcase! is evaluated before the call to #rename, it's modifying
the file variable in-place, so #rename is effectively being called
like this:
It says:
"...can't convert nil into String (Type error)..."
I think you're mistaking the source of your error here. Check this out
(ri String#downcase!):
Downcases the contents of _str_, returning +nil+ if no changes were
made.
So you're call to +downcase!+ is returning nil in the cases where
+file+ was already downcased. When +File.rename+ sees that nil and
tries to convert it to a String, it raises the error you see.
Try using +String#downcase+ instead (note the lack of the exclamation
point).
Jacob Fugal
I see. Thanks a lot, Jacob. There's danger in my scripting there. I'll
try it without the exclamation.