Sth. wrong with File.file? (or with me)

M

Michael Weller

Hi!
I wrote this code to walk a file tree from a given starting directory:

def each_dir(start_dir, &action)
files = Dir.new(start_dir).to_a[2..-1] #remove . and ..
files.each do |f|
unless File.file? f then
yield f
each_dir(start_dir << "\\" << f, &action)
end
end
end

But this doesn't work properly because it seems like File.file?
sometimes errs...
I know RTFS ;-) but I couldn't find it :-((
Can someone guide me?

Michael
 
M

Mohammad Khan

Hi!
I wrote this code to walk a file tree from a given starting directory:

def each_dir(start_dir, &action)
puts "start_dir: #{start_dir}"
files = Dir.new(start_dir).to_a[2..-1] #remove . and ..
# Above line will throw an exception
#if start_dir is not a Directory
files.each do |f|
unless File.file? f then
yield f
each_dir(start_dir << "\\" << f, &action)
end
end
end

But this doesn't work properly because it seems like File.file?
sometimes errs...
I know RTFS ;-) but I couldn't find it :-((
Can someone guide me?

Michael

RTFS ... lol
 
R

Robert Klemme

Michael Weller said:
ts said:
"M" == Michael Weller <[email protected]> writes:


M> files = Dir.new(start_dir).to_a[2..-1] #remove . and ..
M> files.each do |f|
M> unless File.file? f then

there is only the filename in `f'

Duh. I was almost sure it was me :))
svg% ls yyy
aaa
svg%

svg% ruby -e 'Dir.new("yyy").each {|f| p f}'
"."
".."
"aaa"
svg%

you must add `start_dir' for the test File::file?

you can also look at Find::find

svg% ruby -rfind -e 'Find.find("yyy") {|f| p f}'
"yyy"
"yyy/aaa"
svg%

Thanks for your help!
Yes,I think Find was what I was initially searching for. Sth. like
Find::prune would have been my next task...

For reasons of completeness: there is also Dir#[] like in

11:11:54 [temp]: ruby -e 'puts Dir["perl/**/*"]'
perl/a.wml
perl/att.pl
perl/bool.pl
perl/env-test.pl
perl/fun.pl
perl/hash.pl
perl/here.pl
perl/interp.pl
perl/method.pl
perl/pin.wml
perl/repl.pl
perl/replace.pl
perl/test-2.pl
perl/test.pl
perl/x
perl/x.html
perl/x.html~
perl/x.js
perl/x.jsf
perl/x.jsf~
perl/x.jsp
perl/x.jsp~
perl/x~

Another note: if you use File.join() to construct path names, the script
will work independent of platform. So the call would look like this then:

ruby -e 'puts Dir[File.join("perl", "**", "*")]'

Drawback of Dir[] is that the array can get quite huge and you can't stop
traversal in between as with find. Also, you can only use file name
pattern criteria for selecting the files but not others like the size or
modification time.

Kind regards

robert
 
J

Jean-Hugues ROBERT

Hi,

I think things should stay the way they are, here is
why.

Things are a little complex about truthness/falseness.
One has to distinguish the "value" of an object from
its "truthness".

Only nil and false are "false" from a "truthness"
perspective. All other objects are "true".

For true? and false? to be somehow usefull, I first felt
that they should relate to the "truthness" of the
object, not its "value". That is very different from
nil? (it checks the value of the object, only The nil
object is nil?).

This leads to:
class Object
def true? ; true ; end
def false? ; not true? ; end
end
class NilClass
def true? ; false ; end
end
class FalseClass
def true? ; false ; end
end
Usage: 1 - Checking truthness
if some_thing.true? then
xxx
end
Usage: 2 - Checking value
if some_thing == true then
xxx
end

On the other hand, one may consider that
checking the value is what matters most,
versus checking the truthness.

This leads to:
class Object
def true? ; false ; end
def false? ; false ; end
end
class TrueClass
def true? ; true ; end
end
class FalseClass
def false? ; true ; end
end
Usage: 1 - Checking the truthness
if some_thing then
xxx
end
Usage: 2 - Checking the value
if some_thing.true? then
xxx
end

Solution 2 (checking values) leads to
code that is slightly smaller (less characters).
Which is probably a good thing by itself.
However, I think that it is fairly unreadable.

As a conclusion, I think that the status quo
is the best solution. Instead of a hard to
understand true?/false?, let's keep an explicit
xxx == true when value matters instead of
truthness.

My 0.2 Euros.

Yours,

JeanHuguesRobert
 
R

Robert Klemme

Jean-Hugues ROBERT said:
Hi,

I think things should stay the way they are, here is
why.

Things are a little complex about truthness/falseness.
One has to distinguish the "value" of an object from
its "truthness".

I'm not sure whether I follow you here: an object *is* the value. There
is no such thing as a value that is distinct from the object. An object
is interpreted as in boolean contexts according to certain rules (false
and nil => false, all others true); you could call this convention
"truthness", yes.
Only nil and false are "false" from a "truthness"
perspective. All other objects are "true".

For true? and false? to be somehow usefull, I first felt
that they should relate to the "truthness" of the
object, not its "value". That is very different from
nil? (it checks the value of the object, only The nil
object is nil?).

This leads to:
class Object
def true? ; true ; end
def false? ; not true? ; end
end
class NilClass
def true? ; false ; end
end
class FalseClass
def true? ; false ; end
end

You can simplify this to

class Object
def true?; self end
def false?; not true? end
end

because it's the standard convention. Basically this adds one level of
indirection (the method call).
Usage: 1 - Checking truthness
if some_thing.true? then
xxx
end
Usage: 2 - Checking value
if some_thing == true then
xxx
end

On the other hand, one may consider that
checking the value is what matters most,
versus checking the truthness.

I never felt the need for "some_thing == true". In which cases do you
need this?
This leads to:
class Object
def true? ; false ; end
def false? ; false ; end
end
class TrueClass
def true? ; true ; end
end
class FalseClass
def false? ; true ; end
end

You can simplify this, too:

class Object
def true?; TrueClass === self end
def false?; FalseClass === self end
end
Usage: 1 - Checking the truthness
if some_thing then
xxx
end
Usage: 2 - Checking the value
if some_thing.true? then
xxx
end

Solution 2 (checking values) leads to
code that is slightly smaller (less characters).
Which is probably a good thing by itself.
However, I think that it is fairly unreadable.

Yep. I find this quite irritating. When I see "if some_thing.true?
then..." I'd expect the truthness of some_thing to be used, not the
outcome of the test whether some_thing is actually the instance 'true'.
As a conclusion, I think that the status quo
is the best solution. Instead of a hard to
understand true?/false?, let's keep an explicit
xxx == true when value matters instead of
truthness.

.... or "TrueClass === xxx" for that matter. Yes. Totally agree.
My 0.2 Euros.

Now we got 0.22 EUR. :)

Kind regards

robert
 
J

Jean-Hugues ROBERT

I'm not sure whether I follow you here: an object *is* the value. There
is no such thing as a value that is distinct from the object. An object
is interpreted as in boolean contexts according to certain rules (false
and nil => false, all others true); you could call this convention
"truthness", yes.

I don't agree. I don't think that an object IS a value.

An object is more than a value, it is made of:
an identity
a value (or state, or attributes, or ...)
a behavior
Well... that's the way I learned OO.

Two objects can sometime have the same "value", this
is how == compares for equality.

When I draw a line between "object" and "value" it is
about those special objects that compare equal to themselves
only. These are always immutable objects. For example,
no two objects can have the same value 3, because 3
is an immutable integer. The same is true for true, false,
nil. On the other hand, two different strings can both
be valued "3". So, in my mind, 3 is a value, whereas
"3" is an object (whose initial value is "3"). To me
values are objects with some semantic restrictions.
You can simplify this to

class Object
def true?; self end
def false?; not true? end
end

because it's the standard convention. Basically this adds one level of
indirection (the method call).

But then: nil.true? => nil; I was expecting true, xxx? methods should
return a boolean I think.
I never felt the need for "some_thing == true". In which cases do you
need this?

I don't. But the original poster may have a different answer I guess.
You can simplify this, too:

class Object
def true?; TrueClass === self end
def false?; FalseClass === self end
end

I suspect that this is less efficient. My
verbose code leverage the efficient method
dispatching of the interpreter (versus the
additional === test).
Yep. I find this quite irritating. When I see "if some_thing.true?
then..." I'd expect the truthness of some_thing to be used, not the
outcome of the test whether some_thing is actually the instance 'true'.


.... or "TrueClass === xxx" for that matter. Yes. Totally agree.


Now we got 0.22 EUR. :)

You make my day ;-)
Kind regards
robert

Yours,
JeanHuguesRobert
 
M

Mohammad Khan

The main reason I brought up this issue is:
to make differentiation between "a value in boolean context" and "its
real value"

Example,
a = Foo.new
b = nil

a is *true* in boolean context but it is not really a TrueClass or true.
again, b is 'false' in a boolean context but it is not a FalseClass or
false.

thats why, I proposed to have

class Object
def true?
return ( (self == true) or (self === TrueClass) )
end

def false?
return ( (self == false) or (self === FalseClass) )
end
end

so.. again for the above examples:
puts "a is true in boolean context" if a
puts "a is really a *true*" if a.true?


puts "b is false in boolean context" if not b
puts "b is really *false*" if b.false?

if you find true? and false? is not readable or more complex to use, you
might like to write:
puts "a is really a *true*" if a == true
puts "b is really a *false*" if b == false


Thanks again,
Mohammad
 
M

Mohammad Khan

The main reason I brought up this issue is:
to make differentiation between "a value in boolean context" and "its
real value"

Example,
a = Foo.new
b = nil

a is *true* in boolean context but it is not really a TrueClass or true.
again, b is 'false' in a boolean context but it is not a FalseClass or
false.

thats why, I proposed to have

class Object
def true?
return ( (self == true) or (self === TrueClass) )
end

def false?
return ( (self == false) or (self === FalseClass) )
end
end

so.. again for the above examples:
puts "a is true in boolean context" if a
puts "a is really a *true*" if a.true?


puts "b is false in boolean context" if not b
Correction, please read
puts "b is false in boolean context" if b
 
R

Robert Klemme

Jean-Hugues ROBERT said:
I don't agree. I don't think that an object IS a value.

An object is more than a value, it is made of:
an identity
a value (or state, or attributes, or ...)
a behavior
Well... that's the way I learned OO.

Hm, I think we use a different notion of "value" here. I'd say that in
Ruby every value is an object - as opposed to Java for example, where
there is a distinction between POD's (int, char, long...) and objects.
Two objects can sometime have the same "value", this
is how == compares for equality.

#== and #equal? are completely independent of values: they form a
convention about when two instances are considered equivalent. For class
Object they have to share the same identity, i.e., every instance is
equivalent to itself only. For other classes (take structs as an example)
equivalence is defined recursively via equivalence of instance variables.
When I draw a line between "object" and "value" it is
about those special objects that compare equal to themselves
only. These are always immutable objects.

That last statement is not true:

class Foo
attr_accessor :bar
end

Instances of Foo will only be equal to themselfs but they are not
immutable. This is because the inherit default behavior of Object.

Neither immutablility nor the definition of equivalence of Fixnums make
them special. What makes Fixnum special is the way those instances are
created and treated internally in the Ruby interpreter (which is merely an
implementation detail from the perspective of the language). But
otherwise they are completely normal - there is no such concept as in
Java, where you can have objects and POD's. Consider this:

class Fixnum
def eql?(x) false end
def ==(x) false end
end
=> false

You can change the definition of Fixnum equivalence at your discretion.
Of course, many things would break if you do, but that's another story.
For example,
no two objects can have the same value 3, because 3
is an immutable integer. The same is true for true, false,
nil. On the other hand, two different strings can both
be valued "3". So, in my mind, 3 is a value, whereas
"3" is an object (whose initial value is "3"). To me
values are objects with some semantic restrictions.

Don't let yourself be fooled by the syntax: the char sequence '3' refers
an object that, in numerical calculations, behaves like the number 3 (i.e.
the mathematical concept). The char sequence '"3"' referns an object that
contains the given characters literally. Again, from the perspective of
the language Ruby, it's an implementation detail, that the object
accessible via '3' is always the same:
=> 7

while it's not for '"3"':
=> 134969516

Of course it makes good sense to make the instance immutable so nobody can
change the state of the instance that the literal 3 refers. You can treat
the object accessible via '3' much the same like others although there are
some restrictions due to the implementation:
=> Fixnum
But then: nil.true? => nil; I was expecting true, xxx? methods should
return a boolean I think.

That's not necessary in Ruby because all values can be treated
meaningfully in a boolean context (as opposed to Java for example).
I don't. But the original poster may have a different answer I guess.

Yeah, probably.
I suspect that this is less efficient. My
verbose code leverage the efficient method
dispatching of the interpreter (versus the
additional === test).

You're definitely right here.
You make my day ;-)

Should I open up a savings account? :)

Unfortunately I have to go now, otherwise my answer would have been more
verbose, I guess. But we can continue this tomorrow. :)

Kind regards

robert
 
J

Jean-Hugues ROBERT

Hi there,

So. What is a value ? What is an object ? What are the
benefits in distinguishing ?

I feel like we should not stick to the implementation
level to understand the difference, because, in Ruby,
everything (almost) is an object.

My understanding is that the value of an object is
something abstract and immutable that captures the
current state of the object.

I feel like this is a well agreed on notion,
for example within RPC mechanisms when the notion
of "by value" versus "by reference" is used.

When something is passed "by value", it is very clear
that the object whose value was passed is not going
to be modified by the invoked procedure.

Now, some class instances don't require an explicit
choice: "by value" or "by reference", because it
does not matter. This is the case for all instances
of the Integer class, as well as for true, false,
nil and so on. I tend to think of objects of such
classes as "values".

The Ruby String class is an interesting example.
A beginner frequent error is to forget that a Ruby
String object is mutable (i.e. is not a value).
I believe that in Java they distinguish things:
String : Immutable
StringBuf : Mutable

To get back to the original post, the issue is
whether true? and false? should test the "value"
of the object *or* its semantic in the context
of a boolean expression (its "truth ness"). If
you know Ruby enough, you understand that false?
makes sense only if it tests the value. If you
are a beginner, you probably get confused. On
the other hand the current "if xx == false then"
should be readable enough for a beginner to
understand that the condition is not met if
xx is nil.

Yours,

JeanHuguesRobert

EOM
 
L

Logan Capaldo

Well I have written true? and false? methods in the past. Forgetting
the best implementation at the moment I use it because I find things
like:

if a.nil?.false?
....
end

more readable than

if not a.nil?
....
end
 
A

Austin Ziegler

The main reason I brought up this issue is: to make
differentiation between "a value in boolean context" and "its real
value"

Why? This is the ultimate question that I don't think has been
answered at all. Why is #true? and #false superior to explicit
tests? Note that I'm not referring to the alternative directions
inspired by your post (e.g., #if_true and #if_false), but your
suggestion that "foo.true?" is better than "foo == true".
class Object
def true?
return ( (self == true) or (self === TrueClass) )
end

def false?
return ( (self == false) or (self === FalseClass) )
end
end

This is improperly written. +true+, +false+, and +nil+ are the only
possible values of TrueClass, FalseClass, and NilClass,
respectively. Thus, self == true and TrueClass === self (note the
inversion of parameters on the call to #===) are the same test. You
can more efficiently write what you want as:

class Object
def true?
false
end

def false?
false
end
end

class TrueClass
def true?
true
end
end

class FalseClass
def false?
true
end
end

(This is, more or less, how nil? is written. Object#nil? returns
false; NilClass#nil? returns true.)
so.. again for the above examples:
puts "a is true in boolean context" if a
puts "a is really a *true*" if a.true?

Why is this better than "if a == true"
puts "b is false in boolean context" if not b

Try "unless b".

-austin
 
A

Austin Ziegler

Well I have written true? and false? methods in the past. Forgetting
the best implementation at the moment I use it because I find things
like:

if a.nil?.false?
....
end

more readable than

if not a.nil?
....
end

unless a.nil?
....
end

-austin
 
L

Logan Capaldo

Well that was just one example, of course I know about unless. I'm not
trying to get into a philosphically argument about unless vs. not v.s
false? The problem I have with unless is its starts looking weird if
its a multiway branch ie
if a
elsif b
elsif c
else

etc.
 
H

Hal Fulton

Jean-Hugues ROBERT wrote:

[snip]
As a conclusion, I think that the status quo
is the best solution. Instead of a hard to
understand true?/false?, let's keep an explicit
xxx == true when value matters instead of
truthness.

I agree, and well said.

Hal
 
M

Mohammad Khan

Why? This is the ultimate question that I don't think has been
answered at all. Why is #true? and #false superior to explicit
tests? Note that I'm not referring to the alternative directions
inspired by your post (e.g., #if_true and #if_false), but your
suggestion that "foo.true?" is better than "foo == true".


This is improperly written. +true+, +false+, and +nil+ are the only
possible values of TrueClass, FalseClass, and NilClass,

Yes, I wrote it improperly, sorry about that.

class Object
def true?
return self == true
end

def false?
return self == false
end
end
respectively. Thus, self == true and TrueClass === self (note the
inversion of parameters on the call to #===) are the same test. You
can more efficiently write what you want as:

class Object
def true?
false
end

def false?
false
end
end

You might noticed from my previous posting, the reason to I want to have
#true? and #false?

Example:
a = true
b = false

using my 'class Object'
a.true? -> true
b.false? -> true

using your 'class Object'
a.true? -> false
b.false? -> false
which are wrong according to my proposed #true? and #false?

class TrueClass
def true?
true
end
end

class FalseClass
def false?
true
end
end

(This is, more or less, how nil? is written. Object#nil? returns
false; NilClass#nil? returns true.)


Why is this better than "if a == true"

I think, its a personal taste.
I like "a.nil?" more than "a == nil"
same way, I like a.true? than a == true
when I consider 'a' in boolean context.. i write . .. " if a"
when I need to make sure that 'a' is really a 'true'.. I write a.true?,
you might write it a == true.

"We live in a free world"
;-)
 
A

Austin Ziegler

Well that was just one example, of course I know about unless. I'm not
trying to get into a philosphically argument about unless vs. not v.s
false? The problem I have with unless is its starts looking weird if
its a multiway branch ie
if a
elsif b
elsif c
else

In that case -- pun intended -- I use case statements, e.g.:

case
when a
when b
when c
else
end

-austin
 
A

Austin Ziegler

You might noticed from my previous posting, the reason to I want
to have #true? and #false?

No, I didn't. Not anything convincing, at any rate. It seemed to
boil down to "I don't think that a == b is sufficiently OO", which
is certainly not a good reason, IMO. Why do you not like "a ==
true"?
Example:
a = true
b = false

using my 'class Object'
a.true? -> true
b.false? -> true

using your 'class Object'
a.true? -> false
b.false? -> false
which are wrong according to my proposed #true? and #false?

Not if you actually did what I said, which was *NOT* just adding
#true? and #false? to Object. Look again; it does what you want and
it does it cleaner than your == test.
I think, its a personal taste.

That rather goes against (IMO) sensible program design, especially
if you're going to work with others.
I like "a.nil?" more than "a == nil"
same way, I like a.true? than a == true
"We live in a free world"

Yes, we do. I don't think, however, that the Ruby world needs #true?
and #false?

-austin
 
M

Mohammad Khan

No, I didn't. Not anything convincing, at any rate. It seemed to
boil down to "I don't think that a == b is sufficiently OO", which
is certainly not a good reason, IMO. Why do you not like "a ==
true"?

Personal taste! May be I am fond of wired taste !!
Sorry for trying to share my wired taste with you.
Not if you actually did what I said, which was *NOT* just adding
#true? and #false? to Object. Look again; it does what you want and
it does it cleaner than your == test.


That rather goes against (IMO) sensible program design, especially
if you're going to work with others.



Yes, we do. I don't think, however, that the Ruby world needs #true?
and #false?

well, we need to know first before using something.
If you are going to use #true?, you need to know what it does.
I am saying this, for your reply about work with others.
We really don't have Object#true? in ruby. If you see #true? in my code,
you got to look around my code to see what it does?
Same way, If I work with you, you might have some new
opinion/idea/concept that I am not familiar with. In that case, I will
have to do the same.


Mohammad
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top