Pathname's each_entry

Hi all,

I noticed that the following code

require ‘pathname’
p = Pathname.new(‘Test’)
p.each_entry { | f | puts f.exist? }

does not work as I would expect.
I’m expecting that any returned object exists otherwise it wouldn’t be
returned.
If ‘Test’ is a folder containing a single file, the iterator returns
three objects, and rightly so: . … and the file, but only the first two
objects (directories) exist, not the file. Is this the expected
behavior?

Thanks in advance,

Claudio

On Oct 2, 1:22 pm, Claudio G. [email protected] wrote:

returned.
Nope, Pathname.new doesn’t enforce that a particular pathname exists
on your filesystem. That’s up to you.

Regards,

Dan

Daniel B. wrote:

Nope, Pathname.new doesn’t enforce that a particular pathname exists
on your filesystem. That’s up to you.

Can you please clarify?
If I ask Pathname to return the entries that exist within a folder, then
by definition the objects returned must exist.

Claudio

Daniel B. wrote:

Hm, you’re right. I was thinking each_entry simply yielded each piece
of the path.

Trying using it in conjunction with
File.expand_path and see if that works.

I tried that before starting this thread

Claudio

On Oct 2, 2:03 pm, Claudio G. [email protected] wrote:

Daniel B. wrote:

Nope, Pathname.new doesn’t enforce that a particular pathname exists
on your filesystem. That’s up to you.

Can you please clarify?
If I ask Pathname to return the entries that exist within a folder, then
by definition the objects returned must exist.

Hm, you’re right. I was thinking each_entry simply yielded each piece
of the path.

I think you’re getting false because Pathname#exist? isn’t expanding
the path on the test. Trying using it in conjunction with
File.expand_path and see if that works.

Regards,

Dan

On Fri, Oct 3, 2008 at 7:20 AM, Claudio G. [email protected]
wrote:

Claudio

Try this:

require ‘pathname’
path = Pathname.new(‘Test’)
path.each_entry { | f |
p [f, f.exist?, f.expand_path, path.join(f), path.join(f).exist?]
}

>> [#Pathname:., true, #Pathname:/Users/ohalps01/scratch,

#Pathname:Test, true]

>> [#Pathname:.., true, #Pathname:/Users/ohalps01, #Pathname:.,

true]

>> [#Pathname:hello, false,

#Pathname:/Users/ohalps01/scratch/hello, #Pathname:Test/hello,
true]

It appears that each_entry yields just the basename, without any
context.

Regards,
Sean

Sean O’halpin wrote:

It appears that each_entry yields just the basename, without any
context.

You’re right.

require ‘pathname’
p = Pathname.new(‘C:/’) # the same issue happens in Ubuntu
p.each_entry { | x | puts x.expand_path }

This code does not expand the path by prepending C:/, which I think
would be the wanted behavior: it prepends the current working directory.

In order to get my working directory I have to code as follows:

require ‘pathname’
p = Pathname.new(‘C:/’)
p.each_entry { | x | puts x.expand_path(‘C:/’) }

So I’ve had a look at the source code for Pathname and each_entry, and
whenever each_entry iterates over the file system objects (located
within p in my case), the entry x is initialized simply with the name
(in this case the name of the file within C:/) and the link with C:/ is
lost forever, so while p knows about C:/, x does not.

The problem I think is that each_entry is implemented as:

def each_entry(&block)
  Dir.foreach(@path) {|f| yield self.class.new(f) }
end

while I would prefer the following:

def each_entry(&block)
Dir.foreach(@path) {|f| yield self.class.new(@path+f) }
end

Thanks,

Claudio