Why doesn't Perl complain about this bareword?

R

Ronny

By chance I found out that no error is issued on the following
program:

perl -w -e 'use strict; print(Does::Not::Exist,"\n")'

Instead, "Does::Not::Exist" is printed. Shouldn't there be a warning
about
the improper use of a bareword? Similarily, the program

perl -w -e 'use strict; system(Does::Not::Exist,"\n")'

results in the message

Can't exec "Does::Not::Exist": No such file or directory at -e line 1.

which too seems to suggest that Does::Not::Exist is simply interpreted
as string.
But when I use it like this:

perl -w -e 'use strict; print(ref(Does::Not::Exist),"\n")'

I get the more reasonable:

Bareword "Does::Not::Exist" not allowed while "strict subs" in use at -
e line 1.

Why is this bareword treated differently in these contexts?

Ronald
 
B

Ben Bullock

Ronny said:
By chance I found out that no error is issued on the following
program:

perl -w -e 'use strict; print(Does::Not::Exist,"\n")'

Instead, "Does::Not::Exist" is printed. Shouldn't there be a warning
about
the improper use of a bareword?

It seems to be a bug in Perl.
 
S

sheinrich

It seems to be a bug in Perl.

Even stranger:

scripts>perl -we "use strict; print(Does::Not::Exist);"
Name "Does::Not::Exist" used only once: possible typo at -e line 1.
print() on unopened filehandle Exist at -e line 1.

scripts>
 
A

A. Sinan Unur

(e-mail address removed) wrote in
Even stranger:

scripts>perl -we "use strict; print(Does::Not::Exist);"
Name "Does::Not::Exist" used only once: possible typo at -e line 1.
print() on unopened filehandle Exist at -e line 1.

Note that the issue only arises with print. In the case above,
Does::Not::Exist is being taken to refer to a bareword filehandle Exist
in the package Does::Not. It then seems like print wants to print $_ to
this filehandle.

As such, this treatment *may* be consistent with the following excerpt
from perldoc perldata:

Barewords
A word that has no other interpretation in the grammar will be treated
as if it were a quoted string. These are known as "barewords".

In the case of

print Does::Not::Exist;

there does seem to be a valid interpretation of Does::Not::Exist as a
filehandle if one assumes that $_ is printed.

That interpretation is borne out by the following script:

#!/usr/bin/perl

use strict;
use warnings;

print STDERR while $_ = shift;

__END__

Now, let's go back to

print Does::Not::Exist, "\n";

The comma between Does::Not::Exist and "\n" tells print that
Does::Not::Exist is not a filehandle.

Note the following cases:

C:\t> perl -w -Mstrict -e "print Does,Not,Exist, qq{\n}"
No comma allowed after filehandle at -e line 1.

In this case, Does has a valid interpretation as a
bareword filehandle. Thus, strict does not kick in.

C:\t> perl -w -Mstrict -e "print Does'Not'Exist, qq{\n}"
Does::Not::Exist

Note that ' and :: are equivalent, AFAIK.

C:\t> perl -w -Mstrict -e "print Does-Not-Exist, qq{\n}"
Bareword "Exist" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

Note no complaint about Does and Not. I don't know why.

C:\t> perl -w -Mstrict -e "print Does+Not+Exist, qq{\n}"
Bareword "Not" not allowed while "strict subs" in use at -e line 1.
Bareword "Exist" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

Note no complaint about Does. I don't know why.

Again, let's go back to:

C:\t> perl -w -Mstrict -e "print Does::Not::Exist, qq{\n}"
Does::Not::Exist

The comma establishes that Does::Not::Exist is not referring to
filehandle Exist in the package Does::Not.

Recall the excerpt from perldata above. Is there a valid interpretation
of Does::Not::Exist in the current grammar?

I claim that there is. The :: characters in the name establish that it
is the name of a package.

So, it is printed.

Sinan

--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/
 
S

sheinrich

....
Note the following cases:

C:\t> perl -w -Mstrict -e "print Does,Not,Exist, qq{\n}"
No comma allowed after filehandle at -e line 1.

In this case, Does has a valid interpretation as a
bareword filehandle. Thus, strict does not kick in.
But why is the first argument being taken here for a filehandle, in
spite of the comma, and not considered as namespace, as in your other
example?

....
Again, let's go back to:

C:\t> perl -w -Mstrict -e "print Does::Not::Exist, qq{\n}"
Does::Not::Exist

The comma establishes that Does::Not::Exist is not referring to
filehandle Exist in the package Does::Not.

It seems like only Strings containing :: (or ' ) qualify as possible
package names.

Steffen
 
E

Eric Pozharski

A. Sinan Unur said:
(e-mail address removed) wrote in
news:[email protected]:
C:\t> perl -w -Mstrict -e "print Does-Not-Exist, qq{\n}"
Bareword "Exist" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.
Note no complaint about Does and Not. I don't know why.

21:16:29 71 [1:9]$ perl -w -Mstrict -e "print Does - Not - Exist,
qq{\n}"
Bareword "Exist" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.
C:\t> perl -w -Mstrict -e "print Does+Not+Exist, qq{\n}"
Bareword "Not" not allowed while "strict subs" in use at -e line 1.
Bareword "Exist" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.
Note no complaint about Does. I don't know why.

21:17:35 72 [1:9]$ perl -w -Mstrict -e "print Does + Not + Exist,
qq{\n}"
Bareword "Not" not allowed while "strict subs" in use at -e line 1.
Bareword "Exist" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

I believe, that's something with association and/or precedence magic.
And why in first case B<perl> chockes on right C<->, yet in second case
on left C<+>. Perl is full of magic. It makes feel wizardish.
 
A

A. Sinan Unur

(e-mail address removed) wrote in (e-mail address removed):
...
But why is the first argument being taken here for a filehandle, in
spite of the comma, and not considered as namespace, as in your other
example?

Well, it is a bareword. The most natural use of a bareword found
following print is to specify a filehandle in the current package.

The alternative to giving an error message would have been to print Does
which is not what the programmer wanted in 99.9999% of cases of a
bareword following a print followed by a comma.
It seems like only Strings containing :: (or ' ) qualify as possible
package names.

No. DoESnoTExiST is also a valid package name. However, only ' and ::
can be used as separators in a package name.

Sinan

--
A. Sinan Unur <[email protected]>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/
 
B

Ben Morrow

Quoth Eric Pozharski said:
21:16:29 71 [1:9]$ perl -w -Mstrict -e "print Does - Not - Exist,
qq{\n}"
Bareword "Exist" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.
21:17:35 72 [1:9]$ perl -w -Mstrict -e "print Does + Not + Exist,
qq{\n}"
Bareword "Not" not allowed while "strict subs" in use at -e line 1.
Bareword "Exist" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

I believe, that's something with association and/or precedence magic.
And why in first case B<perl> chockes on right C<->, yet in second case
on left C<+>.

The two '-'s are not the same operator:

~% perl -Mstrict -MO=Deparse,-p -e'print Does - Not - Exist, "\n"'
Bareword "Exist" not allowed while "strict subs" in use at -e line
1.
-e had compilation errors.
use strict 'refs';
print(Does ((-'Not') - 'Exist'), "\n");

Since 'Does' is a filehandle, the first is a unary minus and the second
a binary. To allow for modules like Tk which take args (-like =>
'this'), unary minus applies the same autoquoting rules to its (single)
operand as => applies to its left, and (-('String')) is special-cased to
return '-String' (a comment in the source indicates that this behaviour
was specifically added for Tk's benefit).

The two '+'s aren't the same either:

~% perl -Mstrict -MO=Deparse,-p -e'print Does + Not + Exist, "\n"'
Bareword "Not" not allowed while "strict subs" in use at -e line 1.
Bareword "Exist" not allowed while "strict subs" in use at -e line
1.
-e had compilation errors.
use strict 'refs';
print(Does ('Not' + 'Exist'), "\n");

but since unary + is strictly a no-op (it doesn't even show up in the
Deparse output) and doesn't have the same autoquoting behaviour, this
still throws a 'strict' error.
Perl is full of magic. It makes feel wizardish.

Yes. The details of how perl disambiguates filehandles, sub-calls-
without-parens, barewords-used-as-class-names, and barewords-that-
are-strict-errors are really truly evil, and you *will* go insane if you
try too hard to make sense of it :). IMHO it's best to stick to naming
subs and methods in lowercase, classes and packages with initial caps,
and filehandles in all caps; that way you won't get any surprise
misinterpretations.

Ben
 
S

sheinrich

(e-mail address removed) wrote in (e-mail address removed):



Well, it is a bareword. The most natural use of a bareword found
following print is to specify a filehandle in the current package.

The alternative to giving an error message would have been to print Does
which is not what the programmer wanted in 99.9999% of cases of a
bareword following a print followed by a comma.


No. DoESnoTExiST is also a valid package name. However, only ' and ::
can be used as separators in a package name.

That was my point above. (At least I meant it to be ;-)
And because of that I expected Perl to show the same behaviour,
regardless of :: or '.

As we both agree and leaving the comma aside, the first argument could
be a filehandle, a package name or a bareword, just from the look at
it. '::' doesn't change that.

IMHO the actual nature of the beast (or programmer's intention) cannot
be guessed from a following comma but must be determined by a look
into the symbol table.
And if this fails it has to be a bareword and appropriate warning
should be given.

BTW, it could also be a subroutine (with or without a comma
following).

C:\t>perl -w -Mstrict -e "sub DoesExist {} print DoesExist, qq{\n}"


C:\t>perl -w -Mstrict -e "sub DoesExist {} print DoesExist qq{\n}"

C:\t>perl -w -Mstrict -e "print DoesNotExist(), qq{\n}"
Undefined subroutine &main::DoesNotExist called at -e line 1.

Since Perl, in its warnings, never even seems to consider a subroutine
as long as there are no brackets (or '&' sigel), it must already have
taken a look into the symbol table. But why do the warnings elaborate
on all other possibilities?

And why on the other hand, after all other possibilities failed, the
bareword is treated as ordinary string and only if it contains
'::' (the OP's issue).

C:\t>perl -w -Mstrict -e "print DoesNotExist, qq{\n}"
No comma allowed after filehandle at -e line 1.

And why it says "No comma allowed after filehandle" even if it is no
filehandle?

I still find this bahaviour confusing for the user and like Ben Morrow
elsethread, think that it must be caused by some gloomy parts of perl
which we normal users rather shouldn't dare think about.

Cheers, Steffen
 
R

Ronny

(e-mail address removed) wrote innews:[email protected]:



Note that the issue only arises with print. In the case above,
Does::Not::Exist is being taken to refer to a bareword filehandle Exist
in the package Does::Not. It then seems like print wants to print $_ to
this filehandle.

I think the basic reason is that this is simply a bug, as has been
suggested
already. The Perl parser should recognize it as incorrect bareword,
but doesn't,
so it interprets it more or less "by chance" differently:

In the case of print having only this bareword argument, it seems to
consider
it as a filehandle, but even this would be illegal due to parentheses,
as you
can see when you use a valid file handle:

$ perl -we "use strict; print(STDOUT);"
Use of uninitialized value in print at -e line 1.

And, in the examples I gave (using print and system), the bareword
was clearly taken as a string, not as a filehandle.

I sent a bug report to perl.


Ronald
 
C

comp.llang.perl.moderated

By chance I found out that no error is issued on the following
program:

perl -w -e 'use strict; print(Does::Not::Exist,"\n")'

Instead, "Does::Not::Exist" is printed. Shouldn't there be a warning
about
the improper use of a bareword? Similarily, the program

perl -w -e 'use strict; system(Does::Not::Exist,"\n")'

results in the message

Can't exec "Does::Not::Exist": No such file or directory at -e line 1.
which too seems to suggest that Does::Not::Exist is simply interpreted
as string.
But when I use it like this:

perl -w -e 'use strict; print(ref(Does::Not::Exist),"\n")'

I get the more reasonable:

Bareword "Does::Not::Exist" not allowed while "strict subs" in use at -
e line 1.

Why is this bareword treated differently in these contexts?

Perl appears to failover to a literal string interpretation only if
the
package definition doesn't exist:

$ perl -wle 'sub Does::Not::Exist{"foo"};system(Does::Not::Exist)'
Can't exec "foo": No such file or directory at -e line 1.

and,

$ perl -le '*Does::Not::Exist=\*STDOUT;print(Does::Not::Exist
"foo")'
foo


But, then, maybe unexpectedly:

$ perl -wle '*Does::Not::Exist=
\*STDOUT;print(Does::Not::Exist,"foo")'
Does::Not::Existfoo

whereas, the expected behavior might be:

No comma allowed after filehandle at -e line 1

vs:

$ perl -le '*foo=*STDOUT;print( STDOUT, "foo")'
No comma allowed after filehandle at -e line 1.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top