Why is "nil" being included in an array?

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)…”

Thanks,
Peter

On 6/22/06, Peter B. [email protected] wrote:

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 F.

On Jun 22, 2006, at 19:22, Peter B. 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

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 6/22/06, Matthew S. [email protected] 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:

File.rename(‘test’, ‘test’)

I had no idea that Ruby evaluated it that way. Thank you for this
detailed explanation.

Pat

Jacob F. wrote:

On 6/22/06, Peter B. [email protected] wrote:

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 F.

I see. Thanks a lot, Jacob. There’s danger in my scripting there. I’ll
try it without the exclamation.

-Peter

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs