Renaming Files

Hi, I’m just trying to rename a whole load of files in a directory.
Been palying with IRB. My code doesn’t work, no doubt because I
fluffed it.

irb(main):041:0> Dir.entries(’.’).each do |f|
irb(main):042:1* next if f=="." or f=="…"
irb(main):043:1> File.move( f, f.gsub!( /\s/, ‘_’ ) )
irb(main):044:1> end
Errno::ENOENT: No such file or directory -
Animating_Reality_2pm_26th_July_2007.MP3
from /opt/local/lib/ruby/1.8/ftools.rb:106:in stat' from /opt/local/lib/ruby/1.8/ftools.rb:106:inmove’
from (irb):43
from (irb):41:in `each’
from (irb):41
from :0

What’s the best way of doing this, please?

Regards

Gabriel

The problem here is the ! on the gsub. This is changing the contents of
f before it gets passed to the function:

def show(a, b)
puts “[#{a}] [#{b}]”
end

x = “Here is a string”

show(x, x.gsub!(/\s/,’_’))

results in

[Here_is_a_string] [Here_is_a_string]

But change the gsub! to a plain gsub and you get

[Here is a string] [Here_is_a_string]

because a plain gsub returns a copy of the modified string without
modifying the original.

Only use the ! versions when you are absolutely sure you need to.

Alle giovedì 23 agosto 2007, Gabriel D. ha scritto:

irb(main):043:1> File.move( f, f.gsub!( /\s/, ‘_’ ) )

You need gsub, not gsub!. gsub! modifies the string it’s called on (f),
so
File.move the modified string also as first argument. And, since a file
with
the modifed name doesn’t exist, it raises an exception. Besides, gsub!
will
return nil if no replacement happens (i.e, if f doesn’t contain spaces).
This
would also result in an exception. gsub, instead, creates a new string
and
modifies it, so File.move receives two different strings.

I hope this helps

Stefano

On 23 Aug 2007, at 12:27, Peter H. wrote:

Only use the ! versions when you are absolutely sure you need to.

Thank you so much for these replies (Peter & Stefano). That makes
perfect sense. As soon as you pointed out gsub! was doing what is was
supposed to :slight_smile:
Thanks. I just renamed a directory of about 30 files in 0.5 seconds
with that one.

Just another quicky, if I wanna rename all the files in the directory
is what I did OK, using:
next if f=="." or f=="…"

I just feel there must a better way?

Best regards Gabriel

Alle giovedì 23 agosto 2007, Gabriel D. ha scritto:

Just another quicky, if I wanna rename all the files in the directory
is what I did OK, using:
next if f=="." or f=="…"

I just feel there must a better way?

If you want to rename only files, then you should do

next unless File.file? f

This way, you skip not only the given directory and its parent, but also
any
directory inside the current. If you’re sure the given directory
contains
only files, then you’re approach and mine should be equivalent
(although, in
my opinion, mine makes clearer why you’re skipping those entries).

Stefano

On 23 Aug 2007, at 12:54, Stefano C. wrote:

This way, you skip not only the given directory and its parent, but
also any
directory inside the current. If you’re sure the given directory
contains
only files, then you’re approach and mine should be equivalent
(although, in
my opinion, mine makes clearer why you’re skipping those entries).

Stefano

Aha yes, perhaps in my situation both equal, but yours is surely
cleaner and in another situation it would save me from nuking the
subdirs. Thank you, Stefano.

Hi,

Am Donnerstag, 23. Aug 2007, 20:29:26 +0900 schrieb Stefano C.:

Alle giovedì 23 agosto 2007, Gabriel D. ha scritto:

irb(main):043:1> File.move( f, f.gsub!( /\s/, ‘_’ ) )

You need gsub, not gsub!. […] gsub, instead, creates a new string and
modifies it, so File.move receives two different strings.

I suppose the evaluation order of arguments is left to right
and f is handed over to File#move as long as it is the old
version. Yet, before is gets used it becomes modified by its
gsub! method.

Independently from such considerations it is never a good
idea to rely on evaluation orders anywhere else than in
and/&&/or/|| expressions. If File#move were a method taking
a block it surely were no good programming style either to
modify f inside that:

some_method( f) do … ; f.gsub! … ; … end

This is admittedly not a beginners topic and probably far
from what Gabriel expected to meet.

Bertram