What should file test operators return?

5 views
Skip to first unread message

Brian D Foy

unread,
Apr 12, 2007, 2:52:50 PM4/12/07
to perl6-l...@perl.org
At the moment the file test operators that I expect to return true or
false do, but the true is the filename. I expected a boolean, for no
other reason than Perl 6 has them so it might as well use them. The
section on Smart Matching in S03 says that the ~~ doesn't have to
return a boolean, but aside from things liek :s, :M, and :A, what good
would it be not to? I'm happy to update S16 with whatever the answer
is. :)


Here's my code example that motivates this question. For a Llama6
exercise with file test operators, I wanted to create a little table:

for @files -> $file {
printf "%-70s %s %s %s\n",
$file,
$file ~~ :r,
$file ~~ :w,
$file ~~ :x;
}

I get the filename for each part:

foo foo foo

Which I wanted to work like this perl5 (not that I care if it's
different, I just have to explain it to reader)

#!/usr/bin/perl5
foreach ( glob( "*" ) )
{
printf "%30s %s %s %s\n", $_, -r, -w, -x
}


With the Pugs 6.2.13 (r15868), only the ~~ form seems to work, but is
that going to be any different than the other two forms?


pugs> ( "Talks" ~~ :r ).say
Talks
Bool::True
pugs> ( "Talks" ~~ :d ).say
Talks
Bool::True

pugs> "Talks".TEST(:s).say
*** No such method in class Str: &TEST
at <interactive> line 1, column 1-21

pugs> "Talks".:s
Internal error while running expression:
***
Unexpected ":s"
expecting ".", "\187", ">>", "=", operator name, qualified
identifier, variable name, "...", "--", "++", "i", array subscript,
hash subscript or code subscript at <interactive> line 1, column 9
pugs> "Talks".":d"
Internal error while running expression:
***
Unexpected "\":"
expecting ".", "\187", ">>", "=", operator name, qualified
identifier, variable name, "...", "--", "++", "i", array subscript,
hash subscript or code subscript at <interactive> line 1, column 9

Moritz Lenz

unread,
Apr 13, 2007, 5:29:43 AM4/13/07
to perl6-l...@perl.org
Hi,

brian d foy wrote:
> At the moment the file test operators that I expect to return true or
> false do, but the true is the filename.

that helps chaining of file test:

$fn ~~ :t ~~ :x
or something.
If you want a boolean, use
? $fn ~~ :x
or something.

HTH,
Moritz

--
Moritz Lenz
http://moritz.faui2k3.org/ - http://sudokugarden.de/ - http://perl-6.de/

signature.asc

Damian Conway

unread,
Apr 13, 2007, 6:01:13 AM4/13/07
to brian...@gmail.com, perl6-l...@perl.org
On 13/04/07, Moritz Lenz <mor...@casella.verplant.org> wrote:

> If you want a boolean, use
> ? $fn ~~ :x
> or something.

Definitely "or something". Unary ? has the wrong precedence there.
You could write:

for @files -> $file {
printf "%-70s %s %s %s\n",
$file,

true $file ~~ :r,
true $file ~~ :w,
true $file ~~ :x;
}

which could, of course be hyperoperated:

for @files -> $file {
printf "%-70s %s %s %s\n",
$file,

true<< $file <<~~<< (:r, :w, :x);
}


Maybe there also needs to be a "boolean" conversion for printf
(perhaps %t for true?):

for @files -> $file {
printf "%-70s %t %t %t\n",


$file,
$file ~~ :r,
$file ~~ :w,
$file ~~ :x;
}

Which leads to:

for @files -> $file {
printf "%-70s %t %t %t\n",
$file,
$file <<~~<< (:r, :w, :x);
}


Damian

Juerd Waalboer

unread,
Apr 13, 2007, 6:20:40 AM4/13/07
to perl6-l...@perl.org
Damian Conway skribis 2007-04-13 20:01 (+1000):

> Maybe there also needs to be a "boolean" conversion for printf
> (perhaps %t for true?):

I often use "[ ]" and "[X]" to represent true and false in text output.
They resemble checkboxes. I don't think printf needs a boolean output
template, but it would be nice if it were configurable.
--
korajn salutojn,

juerd waalboer: perl hacker <ju...@juerd.nl> <http://juerd.nl/sig>
convolution: ict solutions and consultancy <sa...@convolution.nl>

John Macdonald

unread,
Apr 13, 2007, 9:17:14 AM4/13/07
to Moritz Lenz, perl6-l...@perl.org
On Fri, Apr 13, 2007 at 10:29:43AM +0100, Moritz Lenz wrote:
> Hi,
>
> brian d foy wrote:
> > At the moment the file test operators that I expect to return true or
> > false do, but the true is the filename.
>
> that helps chaining of file test:
>
> $fn ~~ :t ~~ :x
> or something.
> If you want a boolean, use
> ? $fn ~~ :x
> or something.

It might also be useful when the test is being applied to a
junction - it gives the effect of grep.

--

Brandon S. Allbery KF8NH

unread,
Apr 13, 2007, 8:16:15 AM4/13/07
to brian d foy, perl6-l...@perl.org

On Apr 12, 2007, at 14:52 , brian d foy wrote:

> At the moment the file test operators that I expect to return true or
> false do, but the true is the filename. I expected a boolean, for no
> other reason than Perl 6 has them so it might as well use them.

This is documented somewhere already. Pugs does not implement the
spec as documented, though.

File tests are supposed to return something which:
- behaves as a Bool
- stringifies as a filename
- numifies as a file size or as a time, if appropriate
- propagates a stat object (obviating perl5's magic _)

Current Pugs only does the first three, sort of: the size and time
operators return numeric, the others string, all behave appropriately
if used as booleans. This means you mostly get the expected results
for chained tests, at the price of every operator doing its own stat().

My impression is that junction types aren't really "there" yet, so
this is the best that can currently be done.

--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell]
all...@kf8nh.com
system administrator [openafs,heimdal,too many hats]
all...@ece.cmu.edu
electrical and computer engineering, carnegie mellon university
KF8NH


Brian D Foy

unread,
Apr 13, 2007, 8:52:47 AM4/13/07
to perl6-l...@perl.org
In article <A7C986A4-56B8-45A1...@ece.cmu.edu>, Brandon

S. Allbery KF8NH <all...@ece.cmu.edu> wrote:

> On Apr 12, 2007, at 14:52 , brian d foy wrote:
>
> > At the moment the file test operators that I expect to return true or
> > false do, but the true is the filename. I expected a boolean, for no
> > other reason than Perl 6 has them so it might as well use them.
>
> This is documented somewhere already. Pugs does not implement the
> spec as documented, though.

That's part of the problem: finding that somewhere, then makign the
other somewhere's agree with it.

Brian D Foy

unread,
Apr 13, 2007, 9:04:43 AM4/13/07
to perl6-l...@perl.org
In article <A7C986A4-56B8-45A1...@ece.cmu.edu>, Brandon
S. Allbery KF8NH <all...@ece.cmu.edu> wrote:


> File tests are supposed to return something which:
> - behaves as a Bool
> - stringifies as a filename
> - numifies as a file size or as a time, if appropriate
> - propagates a stat object (obviating perl5's magic _)
>
> Current Pugs only does the first three, sort of: the size and time
> operators return numeric, the others string, all behave appropriately
> if used as booleans.

I'm not sure Pugs does that right. The file named "0" (zero) seems to
behave inappropriately. In this example, "foo" and "0" are real files,
and "not there" is not a file that exists:

pugs> "foo" ~~ :e
"foo"
pugs> true "foo" ~~ :e
Bool::True

pugs> "not there" ~~ :e
Bool::False
pugs> true "not there" ~~ :e
Bool::False

pugs> "0" ~~ :e
"0"
pugs> true "0" ~~ :e
Bool::False

Again, I don't really mind whatever the answer is as long as I can
document it. :)

Brian D Foy

unread,
Apr 13, 2007, 8:52:49 AM4/13/07
to perl6-l...@perl.org
In article <461F4D87...@casella.verplant.org>, Moritz Lenz
<mor...@casella.verplant.org> wrote:


> brian d foy wrote:
> > At the moment the file test operators that I expect to return true or
> > false do, but the true is the filename.

> that helps chaining of file test:
>
> $fn ~~ :t ~~ :x
> or something.

That's fine, but the example in S16 shows that as a junction:

$fh ~~ :t & :x

I don't mind the answer being whatever it is as long as it's really the
answer that I can tell newbies and point to in the docs. :)

Brian D Foy

unread,
Apr 13, 2007, 9:15:21 AM4/13/07
to perl6-l...@perl.org

> Hi,
>
> brian d foy wrote:
> > At the moment the file test operators that I expect to return true or
> > false do, but the true is the filename.
>
> that helps chaining of file test:
>
> $fn ~~ :t ~~ :x
> or something.

I thought that returning a stat buffer was supposed to handle the case
of chained file test operators.

S16 will also need a fix-up for this text, I think:

"Also note that, for the superuser on the local filesystems, the :r,
:R, :w, and :W tests always return 1,"

Brandon S. Allbery KF8NH

unread,
Apr 13, 2007, 11:09:17 AM4/13/07
to brian d foy, perl6-l...@perl.org

On Apr 13, 2007, at 9:04 , brian d foy wrote:

> In article <A7C986A4-56B8-45A1...@ece.cmu.edu>, Brandon
> S. Allbery KF8NH <all...@ece.cmu.edu> wrote:
>
>
>> File tests are supposed to return something which:
>> - behaves as a Bool
>> - stringifies as a filename
>> - numifies as a file size or as a time, if appropriate
>> - propagates a stat object (obviating perl5's magic _)
>>
>> Current Pugs only does the first three, sort of: the size and time
>> operators return numeric, the others string, all behave appropriately
>> if used as booleans.
>
> I'm not sure Pugs does that right. The file named "0" (zero) seems to

I'm not surprised; as I said, the current behavior is basically a
placeholder. In the final implementation the "real" value will be
the stat structure, which won't have the 0 vs. '0' ambiguity.

Larry Wall

unread,
Apr 13, 2007, 1:13:14 PM4/13/07
to perl6-l...@perl.org
On Fri, Apr 13, 2007 at 08:01:13PM +1000, Damian Conway wrote:
: Maybe there also needs to be a "boolean" conversion for printf
: (perhaps %t for true?):

Seems insufficiently general. However, I note that booleans are
an enum, and by default stringify to Bool::True or Bool::False.
Maybe %t stands for "terse", which stringifies to True and False, and
in general stringifies any enum to its unqualified name rather than
its qualified name. Kind of a shame %e is taken. On the other hand,
maybe wasting a printf char on this is still insufficiently general,
and it should just be a .terse or .key method of some sort feeding
to a normal %s.

Larry

Larry Wall

unread,
Apr 13, 2007, 12:42:07 PM4/13/07
to perl6-l...@perl.org
On Thu, Apr 12, 2007 at 01:52:50PM -0500, brian d foy wrote:
: At the moment the file test operators that I expect to return true or

: false do, but the true is the filename.

You've just dug up a pugsian fossil.

: I expected a boolean, for no


: other reason than Perl 6 has them so it might as well use them. The
: section on Smart Matching in S03 says that the ~~ doesn't have to
: return a boolean, but aside from things liek :s, :M, and :A, what good
: would it be not to? I'm happy to update S16 with whatever the answer
: is. :)

The intent of moving from the

-r -w -x $file

form to the

$file ~~ :r & :w & :x

form was to get rid of the klunky, inflexible statbuffer propagation
mechanism, which (without an temp var) could only do "and" and not
"or", and didn't work well syntactically in "when" statements. Plus
it forced the user to worry about statbuf caching, which probably just
ought to timeout automatically since it assumes we're the only person
accessing the filesystem, a bogus assumption in the face of any kind
of multiprocessing.

So the new filetests just return a simple value, generally Bool or Num.
To get a statbuf object you now use an explicit stat or lstat. Such an
object should probably stringify to "Stat('filename')" or some such, so
that the filename "0" comes out "Stat('0')".

I will attempt to clarify S03, though my brain is still a little
fuzzy this week for a variety of unrelated reasons.

: Here's my code example that motivates this question. For a Llama6


: exercise with file test operators, I wanted to create a little table:
:
: for @files -> $file {
: printf "%-70s %s %s %s\n",
: $file,
: $file ~~ :r,
: $file ~~ :w,
: $file ~~ :x;
: }

I think I would now write that more like:

for @files -> $file {
given stat $file {
printf "%-70s %s %s %s\n", $file, .:r, .:w, .:x;
}
}

: Which I wanted to work like this perl5 (not that I care if it's


: different, I just have to explain it to reader)
:
: #!/usr/bin/perl5
: foreach ( glob( "*" ) )
: {
: printf "%30s %s %s %s\n", $_, -r, -w, -x
: }
:
:
: With the Pugs 6.2.13 (r15868), only the ~~ form seems to work, but is
: that going to be any different than the other two forms?

The current pugs implementation is just translating to the old form
underneath, so it's not surprising it's a bit off. That's the sort
of thing that happens when the language designer gives the language
implementor whiplash. However, I rather suspect the interpersonal
metaphorical meaning was lost on the physicist/comic who decided that
the 3rd derivative of position should be called "jerk". :)

Larry

Mark J. Reed

unread,
Apr 13, 2007, 3:46:53 PM4/13/07
to brian d foy, perl6-l...@perl.org
I think I need to reread the docs. What's the colon in the method calls for?

(That is, why is it $stat_obj.:r instead of just $stat_obj.r ?)

On 4/13/07, brian d foy <brian...@gmail.com> wrote:
> In article <20070413164...@wall.org>, Larry Wall


> <la...@wall.org> wrote:
>
> > On Thu, Apr 12, 2007 at 01:52:50PM -0500, brian d foy wrote:
>
> > : Here's my code example that motivates this question. For a Llama6
> > : exercise with file test operators, I wanted to create a little table:
> > :
> > : for @files -> $file {
> > : printf "%-70s %s %s %s\n",
> > : $file,
>
>
>
>

> > I think I would now write that more like:
> >
> > for @files -> $file {
> > given stat $file {
> > printf "%-70s %s %s %s\n", $file, .:r, .:w, .:x;
> > }
> > }
>
>

> Hmmm, that's a good little bit of code, as was Damian's use of the
> hyper-operator. The trick is to figure how how much I can use in Llama
> 6 without scaring off the reader. :)
>
> I'm actually starting at the back of the book so I know what I have to
> put in the front of the book to get that far. In previous Llamas the
> file tests operators came before stat, but maybe this answer is a good
> end-of-chapter sorta thing.
>
> I'll also have to think about using given {} merely as a topicalizer
> too, I guess, although showing it next to an explicit assignment to $_.
>
> :)
>


--
Mark J. Reed <mark...@mail.com>

Brian D Foy

unread,
Apr 13, 2007, 3:42:17 PM4/13/07
to perl6-l...@perl.org
In article <20070413164...@wall.org>, Larry Wall
<la...@wall.org> wrote:

> On Thu, Apr 12, 2007 at 01:52:50PM -0500, brian d foy wrote:

> : Here's my code example that motivates this question. For a Llama6
> : exercise with file test operators, I wanted to create a little table:
> :
> : for @files -> $file {
> : printf "%-70s %s %s %s\n",
> : $file,

> I think I would now write that more like:
>
> for @files -> $file {
> given stat $file {
> printf "%-70s %s %s %s\n", $file, .:r, .:w, .:x;
> }
> }

Brian D Foy

unread,
Apr 13, 2007, 6:03:47 PM4/13/07
to perl6-l...@perl.org
In article
<f60fe000704131246x539...@mail.gmail.com>, Mark J.
Reed <mark...@mail.com> wrote:

> I think I need to reread the docs. What's the colon in the method calls for?
>
> (That is, why is it $stat_obj.:r instead of just $stat_obj.r ?)

I can't answer the "why" question, but the stuff in S02 might help you.
Look for "generalized adverbial form":

http://feather.perl6.nl/syn/S02.html

The file test is really an adverbial pair (and see the message about
pairs that I just posted).

Larry just updated S03 with some clarification on file tests. Look at
the section on "Changes to Perl 5 Operators"

http://feather.perl6.nl/syn/S03.html

Reply all
Reply to author
Forward
0 new messages