[comp.lang.perl] interesting JAPH -- weird bug

pem@yarra-glen.aaii.oz.au (Paul E. Maisano) (04/25/91)

This JAPH runs on my sparc, SUNOS4.1.1, perl 4.003
(I think you have to save it to a file, though)
-----
#!/usr/local/bin/perl
$_ = ">/dev/tty";
length < 0 && /bin/echo Just another perl hacker $_
-----

If I use "length($_)" instead, then perl behaves as it should.
I normally don't use "length" without an argument since I've seen it
cause problems before (because of precedence) but I'm intrigued by what
is going on here.

Why is the stuff after "&&" being passed to the shell?

If I add any other lines to the end of the code, perl won't digest it.
It does not happen if I change the "< 0" to a "> 0" either.

---
Paul Maisano

merlyn@iwarp.intel.com (Randal L. Schwartz) (04/25/91)

In article <1991Apr25.014633.20386@yarra-glen.aaii.oz.au>, pem@yarra-glen (Paul E. Maisano) writes:
| #!/usr/local/bin/perl
| $_ = ">/dev/tty";
| length < 0 && /bin/echo Just another perl hacker $_
|
| If I use "length($_)" instead, then perl behaves as it should.
| I normally don't use "length" without an argument since I've seen it
| cause problems before (because of precedence) but I'm intrigued by what
| is going on here.
| 
| Why is the stuff after "&&" being passed to the shell?
| 
| If I add any other lines to the end of the code, perl won't digest it.
| It does not happen if I change the "< 0" to a "> 0" either.

Digging out The Book, cuz I know we talked about this somewhere...

Yes, here it is, on page 86 (where's my scanner? :-):

	Another funny thing about named unary operators [like length]
	is that many of them default to $_ if you don't supply an
	argument.  HOWEVER.  If the thing following the named unary
	operator looks like it *might* be the start of an argument,
	Perl will get confused.  When the next character in your
	program is one of the following characters, the Perl tokener
	returns different token types depending on whether a term or
	operator is expected:

		+, -, *, / <, ., ?, %, &
		[full table deleted]

It goes on to explain why your < is actually being interpreted as the
beginning of a <foo> glob.  What *isn't* described right there is that
<foo> is handed to the shell for expansion, and so, yes indeed, your
/bin/echo is getting handed right to the shell.

I've been publicly thwacked for creating JAPH's that depend on this
behavior, though, so don't count on it in Perl 4.17, or whatever.
Larry could eventually rewrite <foo> so that it doesn't call the shell
at all.

print <;echo Just another Perl hacker,> # :-)
-- 
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III      |
| merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Intel: putting the 'backward' in 'backward compatible'..."====/