Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   stat() bug (http://www.velocityreviews.com/forums/t894885-stat-bug.html)

ssojoodi@gmail.com 10-27-2005 04:08 PM

stat() bug
 
Hello,

While debugging a Perl script, I came across a statement like this:

my @myarray = ("str1", "str2", "str3", "str4");
my $foo = (stat(@myarray))[2];
print $foo;

[result]: str3

I know that this is not the proper usage of the stat function, but I'm
wondering why this script works! I could not find documentation on
this within the perlfunc manual, so I figured this may be a bug.

Any ideas?

Regards,
Sahand


Paul Lalli 10-27-2005 04:47 PM

Re: stat() bug
 
ssojoodi@gmail.com wrote:
> While debugging a Perl script, I came across a statement like this:
>
> my @myarray = ("str1", "str2", "str3", "str4");
> my $foo = (stat(@myarray))[2];
> print $foo;
>
> [result]: str3
>
> I know that this is not the proper usage of the stat function, but I'm
> wondering why this script works! I could not find documentation on
> this within the perlfunc manual, so I figured this may be a bug.
>
> Any ideas?


Running the above code through -MO=Deparse shows us:
my(@myarray) = ('str1', 'str2', 'str3', 'str4');
my $foo = (stat @myarray)[2];
print $foo;

>From that, you can see that '@myarray' is not being passed as an

argument to stat, but rather that array is being expanded so that the
expression is really saying:
(stat 'str1', 'str2', 'str3', 'str4')[2]

stat is defined as a unary operator, so `stat 'str1'` binds more
tightly than does the comma operator. Therefore, the list that's
created above is the list containing: (return_val_of_stat('str1'),
'str2', 'str3', 'str4')

Since the entire operation is being done in scalar context (that is,
you are assigning to the scalar variable $foo, the stat() call is also
done in scalar context, so it simply returns a true or false value, as
defined by the relevant perldoc.

You are then taking the third element of that list, which is 'str3'.

(Please note that I am mildly confused as to why @myarray isn't forced
into scalar context by the stat call, rather than expanded into a list,
but this does explain the results that are created)

Paul Lalli


usenet@DavidFilmer.com 10-27-2005 04:54 PM

Re: stat() bug
 
ssojoodi@gmail.com wrote:
> my @myarray = ("str1", "str2", "str3", "str4");
> my $foo = (stat(@myarray))[2];
> print $foo;
> [result]: str3
>
> I know that this is not the proper usage of the stat function, but I'm
> wondering why this script works!


I'm not sure if you could call it a 'bug' because, as you say, it's not
the proper use of the function.

But it does seem it ought to throw at least a warning. Interestingly
enough:

#!/usr/bin/perl
use strict; use warnings;
my @myarray = ("str1", "str2", "str3", "str4");
print stat @myarray;
__END__

[output:]str1str2str3

(notice the array has been pop()ped).


Anno Siegel 10-27-2005 05:05 PM

Re: stat() bug
 
<ssojoodi@gmail.com> wrote in comp.lang.perl.misc:
> Hello,
>
> While debugging a Perl script, I came across a statement like this:
>
> my @myarray = ("str1", "str2", "str3", "str4");
> my $foo = (stat(@myarray))[2];
> print $foo;
>
> [result]: str3
>
> I know that this is not the proper usage of the stat function, but I'm
> wondering why this script works! I could not find documentation on
> this within the perlfunc manual, so I figured this may be a bug.
>
> Any ideas?


What's happening is rather bizarre, especially when you play around
with

my @myarray = qw( str0 str1 str2 str3 str4);
my @foo = stat( @myarray[1 .. 4]);
print "@foo\n";

However, since the documentation doesn't say what stat() does when called
with more than one argument, it is rather a case of "Don't do that, then".
I guess bailing out with an error message would be better behavior, but
I'm not filing a bug because of this.

I wouldn't trust a program that uses this construct. What were they
thinking stat() was doing?

Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

Paul Lalli 10-27-2005 05:35 PM

Re: stat() bug
 
usenet@DavidFilmer.com wrote:
> ssojoodi@gmail.com wrote:
> > my @myarray = ("str1", "str2", "str3", "str4");
> > my $foo = (stat(@myarray))[2];
> > print $foo;
> > [result]: str3
> >
> > I know that this is not the proper usage of the stat function, but I'm
> > wondering why this script works!

>
> I'm not sure if you could call it a 'bug' because, as you say, it's not
> the proper use of the function.
>
> But it does seem it ought to throw at least a warning. Interestingly
> enough:
>
> #!/usr/bin/perl
> use strict; use warnings;
> my @myarray = ("str1", "str2", "str3", "str4");
> print stat @myarray;
> __END__
>
> [output:]str1str2str3
>
> (notice the array has been pop()ped).


Not really. The array isn't being changed at all. (examine the
contents of @myarray after the print to verify). What seems to be
happening is that stat is invoking a scalar context on the list
contained in @myarray. Accordingly, the first three values are
evaluated and thrown away, and the fourth value is actually passed to
stat(). Since no such file named 'str4' actually exists on your
system, that stat call returns an empty list. The print then prints
the first through third values as is, followed by the return value of
stat('str4').

You can verify this by replacing these dummy strings with names of
actual files:

$ touch file1.txt
$ touch file2.txt
$ touch file3.txt
$ touch file4.txt
$ perl -Mstrict -w -MData::Dumper
my @files = qw/file1.txt file2.txt file3.txt file4.txt/;
my @results = stat(@files);
print Dumper(\@results);
__END__
$VAR1 = [
'file1.txt',
'file2.txt',
'file3.txt',
51987534,
591538,
33204,
1,
5111,
50,
0,
'0',
1130434354,
1130434354,
1130434354,
8192,
0
];


All very bizarre, regardless.

Paul Lalli


Tad McClellan 10-27-2005 09:31 PM

Re: stat() bug
 
Paul Lalli <mritty@gmail.com> wrote:
> ssojoodi@gmail.com wrote:
>> While debugging a Perl script, I came across a statement like this:
>>
>> my @myarray = ("str1", "str2", "str3", "str4");
>> my $foo = (stat(@myarray))[2];
>> print $foo;
>>
>> [result]: str3
>>
>> I know that this is not the proper usage of the stat function, but I'm
>> wondering why this script works! I could not find documentation on
>> this within the perlfunc manual, so I figured this may be a bug.
>>
>> Any ideas?

>
> Running the above code through -MO=Deparse shows us:
> my(@myarray) = ('str1', 'str2', 'str3', 'str4');
> my $foo = (stat @myarray)[2];
> print $foo;
>
>>From that, you can see that '@myarray' is not being passed as an

> argument to stat, but rather that array is being expanded so that the
> expression is really saying:
> (stat 'str1', 'str2', 'str3', 'str4')[2]
>
> stat is defined as a unary operator, so `stat 'str1'` binds more
> tightly than does the comma operator. Therefore, the list that's
> created above is the list containing: (return_val_of_stat('str1'),
> 'str2', 'str3', 'str4')
>
> Since the entire operation is being done in scalar context (that is,
> you are assigning to the scalar variable $foo, the stat() call is also
> done in scalar context,



The stat call is in *list* context (it is part of a list slice).

The list slice, in turn, is what is in scalar context.


> so it simply returns a true or false value, as
> defined by the relevant perldoc.
>
> You are then taking the third element of that list, which is 'str3'.
>
> (Please note that I am mildly confused as to why @myarray isn't forced
> into scalar context by the stat call,



Me too.


> rather than expanded into a list,
> but this does explain the results that are created)



--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas

SNeelakantan_C@zaplet.com 10-27-2005 10:23 PM

Re: stat() bug
 
Paul, your example provides a good idea of what stat() does. The scalar
context of a list is usually either the count of the number of elements
in the list or the last item of the list.

So the stat call stat(@files) becomes:

[ 'file1.txt', 'file2.txt', 'file3.txt', stat($file[4]) ]

The right thing to to do is to probably discard file1.txt, file2.txt
and file3.txt completely. Also, if file4.txt could not be found, I
would imagine $! or $@ to be set, instead of returning an empty list.

-SN


Tassilo v. Parseval 10-28-2005 06:46 AM

Re: stat() bug
 
Also sprach Tad McClellan:
> Paul Lalli <mritty@gmail.com> wrote:


>> (Please note that I am mildly confused as to why @myarray isn't forced
>> into scalar context by the stat call,

>
>
> Me too.


This looks like a bug to me. CORE::stat has a prototype of '*' which -
when given an array - should yield the array length. This is at least
what happens with user functions having that prototype.

Tassilo
--
use bigint;
$n=71423350343770280161397026330337371139054411854 220053437565440;
$m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($ m+=8)<=200);

Joe Smith 10-31-2005 02:17 AM

Re: stat() bug
 
SNeelakantan_C@zaplet.com wrote:
> stat($file[4])
> Also, if file4.txt could not be found, I
> would imagine $! or $@ to be set, instead of returning an empty list.


Definitely not $@ since eval() is not being used.
You should expect $! to be set _AND_ an empty list.
-Joe


All times are GMT. The time now is 04:44 AM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57