The old File.rename not working again. . .

This always throws me. I keep getting “permission denied” messages when
I simply try to rename files. Here’s my code. The files in the directory
start out without an extension.

Dir.chdir(“F:/images”)
Dir.glob("*").each do |file|
File.new(file, “r”).gets
if $_ =~ /%!PS-Adobe/
newfile = file + “.eps”
File.rename(file, newfile)
end
end

Thanks,
Peter

Hi,

At Sun, 7 Oct 2007 11:15:04 +0900,
Peter B. wrote in [ruby-talk:272952]:

This always throws me. I keep getting “permission denied” messages when
I simply try to rename files. Here’s my code. The files in the directory
start out without an extension.

Dir.chdir(“F:/images”)

Maybe on Windows?

Dir.glob("*").each do |file|
File.new(file, “r”).gets

This leaves the file still opened, and on Windows, it’s
prohibited by the OS to move/rename files while they are
opened.

if /%!PS-Adobe/ =~ IO.open(file) {|f| f.gets}
  File.rename(file, file + ".eps")
end

On Oct 7, 12:07 am, Nobuyoshi N. [email protected] wrote:

  File.rename(file, file + ".eps")
end

Why would he need to open the file at all?

Dir.chdir(“F:/images”)
Dir.glob(“*”).each do |file|
if file =~ /%!PS-Adobe/
newfile = file + “.eps”
File.rename(file, newfile)
end
end

Regards,

Dan

On Oct 7, 7:30 am, Sebastian H. [email protected]
wrote:

Daniel B. wrote:

On Oct 7, 12:07 am, Nobuyoshi N. [email protected] wrote:

if /%!PS-Adobe/ =~ IO.open(file) {|f| f.gets}
  File.rename(file, file + ".eps")
end

Why would he need to open the file at all?

Because he’s checking the first line of the file, not the filename.

Oops, my mistake.

Regards,

Dan

Nobuyoshi N. wrote:

Hi,

At Sun, 7 Oct 2007 11:15:04 +0900,
Peter B. wrote in [ruby-talk:272952]:

This always throws me. I keep getting “permission denied” messages when
I simply try to rename files. Here’s my code. The files in the directory
start out without an extension.

Dir.chdir(“F:/images”)

Maybe on Windows?

Dir.glob("*").each do |file|
File.new(file, “r”).gets

This leaves the file still opened, and on Windows, it’s
prohibited by the OS to move/rename files while they are
opened.

if /%!PS-Adobe/ =~ IO.open(file) {|f| f.gets}
  File.rename(file, file + ".eps")
end

Yes, I’m on Windows. And, yes, it makes sense that it won’t let me do it
because the file is, apparently, still open. But, I guess I’m stumped as
to how I can open the file to check that first line, match against that
first line, close the file, and then be able to rename the filename of
that particular file. Once the file is closed I really can’t do anything
more inside that same if-end loop, can I?

-Peter

Daniel B. wrote:

On Oct 7, 12:07 am, Nobuyoshi N. [email protected] wrote:

if /%!PS-Adobe/ =~ IO.open(file) {|f| f.gets}
  File.rename(file, file + ".eps")
end

Why would he need to open the file at all?

Because he’s checking the first line of the file, not the filename.

Peter B. wrote:

Nobuyoshi N. wrote:

if /%!PS-Adobe/ =~ IO.open(file) {|f| f.gets}
  File.rename(file, file + ".eps")
end

Yes, I’m on Windows. And, yes, it makes sense that it won’t let me do it
because the file is, apparently, still open. But, I guess I’m stumped as
to how I can open the file to check that first line, match against that
first line, close the file, and then be able to rename the filename of
that particular file. Once the file is closed I really can’t do anything
more inside that same if-end loop, can I?

-Peter

This line:

if /%!PS-Adobe/ =~ IO.open(file) {|f| f.gets}    

opens the file, gets the first line, closes the file, and checks the
line against the regex for a match. If there is a match, this code
executes:

  File.rename(file, file + ".eps")
end

That line renames the file.

But, I guess I’m stumped as
to how I can open the file to check that first line, match against that
first line, close the file, and then be able to rename the filename of
that particular file. Once the file is closed I really can’t do anything
more inside that same if-end loop, can I?

What more do you want to do?

This line:

if /%!PS-Adobe/ =~ IO.open(file) {|f| f.gets}    

opens the file, gets the first line, closes the file, and checks the
line against the regex for a match. If there is a match, this code
executes:

  File.rename(file, file + ".eps")
end

That line renames the file.

What more do you want to do?

I want to rename the file(s), and, that’s what’s not working. I’m
getting file permission errors.

Peter B. wrote:

That line renames the file.

What more do you want to do?

I want to rename the file(s), and, that’s what’s not working. I’m
getting file permission errors.

The code posted above gives you permission errors? Or your original code
gives
you permission errors? Because the code posted above really shouldn’t.
If the
code above gives you permission error, it’s not because of open file
handles.
Maybe you don’t have permission to change the contents of the directory
you
are working on?

Jay L. wrote:

On Mon, 8 Oct 2007 01:19:01 +0900, Sebastian H. wrote:

The code posted above gives you permission errors? Or your original code gives
you permission errors? Because the code posted above really shouldn’t. If the
code above gives you permission error, it’s not because of open file handles.

Actually, the code above should give him

TypeError: can’t convert String into Integer

because IO.open wants an integer file descriptor :slight_smile: He wants
Kernel.open.

The working code is:

Dir.glob("*").each do |file|
if /%!PS-Adobe/ =~ open(file) {|f| f.gets}
File.rename(file, file + “.eps”)
end
end

Peter, the key to Nobuyoshi’s change above is that the rename now
happens
outside the Kernel.open block. It doesn’t matter that it happens
inside
the if/end block; that’s not what’s holding the file open - Kernel.open
is.
Now, the only thing that’s done in the block is the gets, and the block
is
closed on the very same line, before the rename happens.

Yes, Jay, that worked! And, I beg your pardon, Nobuyoshi, because, I
rather glibly just glanced over your code thinking you were just
repeating my code.

Now, I have to admit, I really need to look at your code, Jay, because,
to me, it’s like a different “dialect.” My primitive Ruby experience is
showing, I guess. I’ve certainly worked with blocks before, and I’ve
certainly worked with opening files before. And, I thought I was being
clever here by using “gets” for the first time, knowing that I only
wanted to read that first line. Previously, I’ve used File.read a lot,
but, I actually did want to read in the whole file then. But, your
casual use of a black and opening a file here kind of blows me away,
actually.

Thank you everyone.

Cheers,
Peter

“casual use of a block” not “black.” Sorry.

On Mon, 8 Oct 2007 01:19:01 +0900, Sebastian H. wrote:

The code posted above gives you permission errors? Or your original code gives
you permission errors? Because the code posted above really shouldn’t. If the
code above gives you permission error, it’s not because of open file handles.

Actually, the code above should give him

TypeError: can’t convert String into Integer

because IO.open wants an integer file descriptor :slight_smile: He wants
Kernel.open.

The working code is:

Dir.glob("*").each do |file|
if /%!PS-Adobe/ =~ open(file) {|f| f.gets}
File.rename(file, file + “.eps”)
end
end

Peter, the key to Nobuyoshi’s change above is that the rename now
happens
outside the Kernel.open block. It doesn’t matter that it happens
inside
the if/end block; that’s not what’s holding the file open - Kernel.open
is.
Now, the only thing that’s done in the block is the gets, and the block
is
closed on the very same line, before the rename happens.

Jay L. wrote:

In Ruby, though, the object gets destroyed by garbage collection, not by
explicit destruction or stack unwinding. So RAII wouldn’t work; you can
never guarantee when (or if) the resource will be closed. Instead,
resource-wrappers like File often let you specify a block; the wrapper
opens the resource, yields to the block, and closes the resource for you.
It’s just a different wrapping idiom. If you haven’t discovered
http://gotapi.com already, load up the Ruby tab and check out IO#open.

A FAQ on the C++ mailing list is “shouldn’t C++ learn from Java and add
a
‘finally’ keyword”?

Block closures teach us that both RAII and ‘finally’ are hacks, and the
Execute Around Pattern is the Real Deal.

On Mon, 8 Oct 2007 07:40:42 +0900, Peter B. wrote:

Now, I have to admit, I really need to look at your code, Jay, because,
to me, it’s like a different “dialect.”

Me too! I’ve only been doing Ruby for a few years, and then only for
play

  • just started being a pro-fessional this summer. Luckily, Ruby’s so
    natural, you’ll be giving newsgroup advice yourself in just a few
    months.

The “block trick” happens to be one of the first Ruby idioms I read
about.
In C++, people use RAII, Resource Acquisition Is Initialization, where
you
wrap a resource in an object, “open” the resource by creating the
object,
and “close” it by destroying the object.*

In Ruby, though, the object gets destroyed by garbage collection, not by
explicit destruction or stack unwinding. So RAII wouldn’t work; you can
never guarantee when (or if) the resource will be closed. Instead,
resource-wrappers like File often let you specify a block; the wrapper
opens the resource, yields to the block, and closes the resource for
you.
It’s just a different wrapping idiom. If you haven’t discovered
http://gotapi.com already, load up the Ruby tab and check out IO#open.

  • Wasn’t RAII originally called RAIN, Resource Acquisition Is
    iNitialization? I could swear it was, and it certainly seems a more
    memorable choice for an acronym, but Google’s not bearing me out on
    this.
    Then again, that was pre-Google. Anyone?

Peter B. wrote:

Now, I have to admit, I really need to look at your code, Jay, because,
to me, it’s like a different “dialect.”

But, your
casual use of a black and opening a file here kind of blows me away,
actually.

  1. First attempt at writing the code:

f = File.new(file)
line1 = f.gets
f.close

if /%!PS-Adobe/ =~ line1
File.rename(file, “#{file}.eps”)

  1. Hmmm…I think I can make those first three lines shorter. If I use
    a File.open block that I read about in pickaxe, I won’t have to call
    close():

line1 = nil
File.open {|file| line1 = f.gets}

if /%!PS-Adobe/ =~ line1
File.rename(file, “#{file}.eps”)

  1. And, shorter still…:

line1 = File.open {|file| f.gets}

if /%!PS-Adobe/ =~ line1
File.rename(file, “#{file}.eps”)

  1. Hey, but look at 3). line1 appears on each line. So I can take what
    line1 is equal to on the first line and substitute it’s value in the
    second line:

if /%!PS-Adobe/ =~ File.open {|file| f.gets}
File.rename(file, “#{file}.eps”)

In Ruby, though, the object gets destroyed by garbage collection, not by
explicit destruction or stack unwinding. So RAII wouldn’t work; you can
never guarantee when (or if) the resource will be closed. Instead,
resource-wrappers like File often let you specify a block; the wrapper
opens the resource, yields to the block, and closes the resource for
you.
It’s just a different wrapping idiom. If you haven’t discovered
http://gotapi.com already, load up the Ruby tab and check out IO#open.

  • Wasn’t RAII originally called RAIN, Resource Acquisition Is
    iNitialization? I could swear it was, and it certainly seems a more
    memorable choice for an acronym, but Google’s not bearing me out on
    this.
    Then again, that was pre-Google. Anyone?

Well, I’d love to be able to give advice eventually in this forum, to
someone even newbier than me. It’s such a generous forum that I feel I
have to give back in some way. . . .

if /%!PS-Adobe/ =~ File.open {|file| f.gets}
File.rename(file, “#{file}.eps”)

This is not C or Python, Ruby needs an end.

Or a one-liner:

| File.rename(file, “#{file}.eps”) if /%!PS-Adobe/ =~ File.open {|file| f.gets}

mfg, simon … l

On Oct 8, 12:09 pm, Simon K. [email protected] wrote:

if /%!PS-Adobe/ =~ File.open {|file| f.gets}
File.rename(file, “#{file}.eps”)

This is not C or Python, Ruby needs an end.

Or a one-liner:

| File.rename(file, “#{file}.eps”) if /%!PS-Adobe/ =~ File.open {|file| f.gets}

I think that should be

File.rename(file, “#{file}.eps”) if /%!PS-Adobe/ =~ File.open(file){|
f| f.gets}

More terse:

File.rename(file, “#{file}.eps”) if /%!PS-Adobe/ =~ IO.read(file,10)

| File.rename(file, “#{file}.eps”) if /%!PS-Adobe/ =~ File.open {|file| f.gets}

I think that should be

File.rename(file, “#{file}.eps”) if /%!PS-Adobe/ =~ File.open(file){|
f| f.gets}

Yeah, I correct one error and repeat another.

More terse:

File.rename(file, “#{file}.eps”) if /%!PS-Adobe/ =~ IO.read(file,10)

That’s a violation of the DRY principle.

Define PS = ‘%!PS-Adobe’ then

| File.rename(file, “#{file}.eps”) if IO.read(file, PS.length)[PS]

mfg, simon … l

On Oct 8, 5:17 pm, Simon K. [email protected] wrote:

More terse:

File.rename(file, “#{file}.eps”) if /%!PS-Adobe/ =~ IO.read(file,10)

That’s a violation of the DRY principle.

Define PS = ‘%!PS-Adobe’ then

| File.rename(file, “#{file}.eps”) if IO.read(file, PS.length)[PS]

That’s a violation of common sense. ‘%!PS-Adobe’ isn’t going
to change, and therefore 10 won’t need changing. Unjustified
code inflation and a superfluous temporary variable.
Furthermore, why say “.length” when you can say “.size”?
You have a perverse, pronounced propensity for prolixity.