Perl lexer: why does "<=>" eq "=" in the context of <=><=><=>?
Asked Answered
K

4

12

I was just reading the secret pseudo-constants, namely the Space fleet constant

<=><=><=>   Space fleet                 0

This seems to be because the outer <=> is doing something I don't understand. My question is why does

my $foo = <=>;

Set $foo to =? Other non-alphanumerics seem to work too,

my $foo = <=>;
my $foo = <->;
my $foo = </>;

But, alphanumerics don't...

my $foo = <a>;

Moreover, the perlsecret pod is confusing to me,

Even though it looks like a sequence of three spaceship operators, only the middle ship is an actual spaceship. The two outer "spaceships" are actually calls to glob("=").

It doesn't seem to be the case either, as I can't make sense as to why, glob("=") would return =, but glob("a") would return undef -- even if there is a file called a in the current working directory.

What is Perl doing in both of these cases? I assume it's falling back to a literal if the thing inside the <> isn't an alphanumeric -- is that behavior supported?

Keelby answered 6/7, 2018 at 4:26 Comment(0)
K
2

I think I see what's going on,

glob("*asdf*");

Will return only files that have the string asdf in their name because the metacharacter expansion tests for file-exists. However,

glob("asdf");

will always return asdf, regardless of the status of the file. By extension <=> lackinging a metacharacter will also return '='.

Keelby answered 6/7, 2018 at 4:54 Comment(0)
H
9

Where an expression is expected, Perl picks the first of the following that applies:

Where an infix or postfix operator is expected, Perl picks the first of the following that applies:

  • <=> is the numerical comparison operator.
  • <= is otherwise the numerical less-than-or-equal operator.
  • << is the shift operator.
  • < is otherwise the numerical less-than operator.

(The last three might not be relevant here. I added them to cover everything starting with <.)

So,

  • <=><=><=>
    

    is short for

    glob(qq<=>) <=> glob(qq<=>)
    

    which can be written

    glob("=") <=> glob("=")
    

    or

    "=" <=> "="
    

    since a glob pattern with no special glob characters simply returns the pattern.

    It warns "isn't numeric" twice and evaluates to zero.

  • my $foo = <=>;
    

    is short for

    my $foo = glob(qq<=>);
    

    which can be written

    my $foo = glob("=");
    

    or

    my $foo = "=";
    
  • my $foo = <a>;
    

    is short for

    my $foo = readline(a);
    

    It warns "used only once: possible typo" if there are no other mentions of *a.

    It warns "on unopened filehandle" if you haven't previously opened a as a file handle.

Hon answered 6/7, 2018 at 6:20 Comment(1)
This is the only answer that explains why <=> is sometimes interpreted as a uses of glob, and why <a> isn't, which is the very question asked. (It's also the only one that explains why <<> is interpreted as none of those.)Hon
W
6

When in doubt check with -MO=Deparse:

$ perl -MO=Deparse -e '$foo = <=>'

use File::Glob ();
$foo = glob('=');

Spacefleet gives 0 as both operands to <=> are equal,

perl -MO=Deparse -e '$foo = <=><=><=>'

use File::Glob ();
$foo = glob('=') <=> glob('=');
Wozniak answered 6/7, 2018 at 9:12 Comment(0)
G
5
my $foo = <=>;
my $foo = <->;
my $foo = </>;

These are all interpreted as uses of glob. Since there are no *, ?, or […] constructions in their arguments, they expand to the text passed in.

my $foo = <a>;

This is interpreted as reading one line from a file handle called a.

Anyways. <=><=><=> behaves like glob("=") <=> glob("="). Since both sides evaluate to "=", they're equal, and the comparison returns 0.

Gentlemanly answered 6/7, 2018 at 4:36 Comment(0)
K
2

I think I see what's going on,

glob("*asdf*");

Will return only files that have the string asdf in their name because the metacharacter expansion tests for file-exists. However,

glob("asdf");

will always return asdf, regardless of the status of the file. By extension <=> lackinging a metacharacter will also return '='.

Keelby answered 6/7, 2018 at 4:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.