Какие псевдооператоры существуют в Perl 5?

Я в настоящее время документирую все операторы Perl 5's (см. perlopref проект GitHub), и я решил включать псевдооператоры Perl 5's также. Мне псевдооператор в Perl - что-либо, что похоже на оператор, но является действительно больше чем одним оператором или некоторой другой частью синтаксиса. Я зарегистрировал четыре, с которыми я уже знаком:

  • ()= оператор отсчета
  • =()= goatse/countof оператор
  • ~~ скалярный оператор контекста
  • }{ оператор эскимосского поцелуя

Что другие имена существуют для этих псевдооператоров, и Вы знаете о каких-либо псевдооператорах, которые я пропустил?

=head1 Pseudo-operators

There are idioms in Perl 5 that appear to be operators, but are really a
combination of several operators or pieces of syntax. These pseudo-operators
have the precedence of the constituent parts.

=head2 ()= X

=head3 Description

This pseudo-operator is the list assignment operator (aka the countof
operator).  It is made up of two items C<()>, and C<=>.  In scalar context
it returns the number of items in the list X.  In list context it returns an
empty list.  It is useful when you have something that returns a list and
you want to know the number of items in that list and don't care about the
list's contents.  It is needed because the comma operator returns the last
item in the sequence rather than the number of items in the sequence when it
is placed in scalar context.

It works because the assignment operator returns the number of items
available to be assigned when its left hand side has list context.  In the
following example there are five values in the list being assigned to the
list C<($x, $y, $z)>, so C<$count> is assigned C<5>.

    my $count = my ($x, $y, $z) = qw/a b c d e/;

The empty list (the C<()> part of the pseudo-operator) triggers this
behavior.

=head3 Example

    sub f { return qw/a b c d e/ }

    my $count = ()= f();              #$count is now 5

    my $string = "cat cat dog cat";

    my $cats = ()= $string =~ /cat/g; #$cats is now 3

    print scalar( ()= f() ), "\n";    #prints "5\n"

=head3 See also

L and L

=head2 X =()= Y

This pseudo-operator is often called the goatse operator for reasons better
left unexamined; it is also called the list assignment or countof operator.
It is made up of three items C<=>, C<()>, and C<=>.  When X is a scalar
variable, the number of items in the list Y is returned.  If X is an array
or a hash it it returns an empty list.  It is useful when you have something
that returns a list and you want to know the number of items in that list
and don't care about the list's contents.  It is needed because the comma
operator returns the last item in the sequence rather than the number of
items in the sequence when it is placed in scalar context.

It works because the assignment operator returns the number of items
available to be assigned when its left hand side has list context.  In the
following example there are five values in the list being assigned to the
list C<($x, $y, $z)>, so C<$count> is assigned C<5>.

    my $count = my ($x, $y, $z) = qw/a b c d e/;

The empty list (the C<()> part of the pseudo-operator) triggers this
behavior.

=head3 Example

    sub f { return qw/a b c d e/ }

    my $count =()= f();              #$count is now 5

    my $string = "cat cat dog cat";

    my $cats =()= $string =~ /cat/g; #$cats is now 3

=head3 See also

L and L

=head2 ~~X

=head3 Description

This pseudo-operator is named the scalar context operator.  It is made up of
two bitwise negation operators.  It provides scalar context to the
expression X.  It works because the first bitwise negation operator provides
scalar context to X and performs a bitwise negation of the result; since the
result of two bitwise negations is the original item, the value of the
original expression is preserved.

With the addition of the Smart match operator, this pseudo-operator is even
more confusing.  The C function is much easier to understand and you
are encouraged to use it instead.

=head3 Example

    my @a = qw/a b c d/;

    print ~~@a, "\n"; #prints 4

=head3 See also

L, L, and L

=head2 X }{ Y

=head3 Description

This pseudo-operator is called the Eskimo-kiss operator because it looks
like two faces touching noses.  It is made up of an closing brace and an
opening brace.  It is used when using C as a command-line program with
the C<-n> or C<-p> options.  It has the effect of running X inside of the
loop created by C<-n> or C<-p> and running Y at the end of the program.  It
works because the closing brace closes the loop created by C<-n> or C<-p>
and the opening brace creates a new bare block that is closed by the loop's
original ending.  You can see this behavior by using the L
module.  Here is the command C deparsed:

    LINE: while (defined($_ = )) {
        print $_;
    }

Notice how the original code was wrapped with the C loop.  Here is
the deparsing of C:

    LINE: while (defined($_ = )) {
        ++$count if /foo/;
    }
    {
        print "$count\n";
    }

Notice how the C loop is closed by the closing brace we added and the
opening brace starts a new bare block that is closed by the closing brace
that was originally intended to close the C loop.

=head3 Example

    # count unique lines in the file FOO
    perl -nle '$seen{$_}++ }{ print "$_ => $seen{$_}" for keys %seen' FOO

    # sum all of the lines until the user types control-d
    perl -nle '$sum += $_ }{ print $sum'

=head3 See also

L and L

=cut

27
задан Mogsdad 26 January 2018 в 14:37
поделиться

6 ответов

В Perl они обычно называются «секретными операторами».

Частичный список «секретных операторов» можно найти здесь . Самый лучший и наиболее полный список, вероятно, имеется у Philippe Bruhad aka BooK и его доклада Secret Perl Operators , но я не знаю, где он доступен. Вы можете спросить его. Вы, вероятно, сможете почерпнуть еще немного из Обфускация, Гольф и Секретные операторы .

5
ответ дан 28 November 2019 в 05:32
поделиться

Хороший проект, вот несколько:

scalar x!! $value    # conditional scalar include operator
(list) x!! $value    # conditional list include operator
'string' x/pattern/  # conditional include if pattern
"@{[ list ]}"        # interpolate list expression operator
"${\scalar}"         # interpolate scalar expression operator
!! $scalar           # scalar -> boolean operator
+0                   # cast to numeric operator
.''                  # cast to string operator

{ ($value or next)->depends_on_value() }  # early bail out operator
# aka using next/last/redo with bare blocks to avoid duplicate variable lookups
# might be a stretch to call this an operator though...

sub{\@_}->( list )   # list capture "operator", like [ list ] but with aliases
18
ответ дан 28 November 2019 в 05:32
поделиться

Не забудьте про Flaming X-Wing =<>=~

Список рассылки Fun With Perl окажется полезным для ваших исследований.

3
ответ дан 28 November 2019 в 05:32
поделиться

Операторы «идет к» и «к нему обращается»:

$x = 10;
say $x while $x --> 4;
# prints 9 through 4

$x = 10;
say $x while 4 <-- $x;
# prints 9 through 5

Они не уникальны для Perl.

3
ответ дан 28 November 2019 в 05:32
поделиться

У вас есть два оператора "countof" (псевдо-)оператора, и я не вижу разницы между ними.

Из примеров "оператора countof":

my $count = ()= f();              #$count is now 5
my $string = "cat cat dog cat";
my $cats = ()= $string =~ /cat/g; #$cats is now 3

Из примеров "оператора goatse/countof":

my $count =()= f();              #$count is now 5
my $string = "cat cat dog cat";
my $cats =()= $string =~ /cat/g; #$cats is now 3

Оба набора примеров идентичны, modulo whitespace. Какие у вас есть основания считать их двумя разными псевдооператорами?

1
ответ дан 28 November 2019 в 05:32
поделиться

Из этого вопроса я обнаружил оператор %{{}} для преобразования списка в хэш. Полезно в контекстах, где требуется хэш-аргумент (а не хэш-присвоение).

@list = (a,1,b,2);
print values @list;        # arg 1 to values must be hash (not array dereference)
print values %{@list}      # prints nothing
print values (%temp=@list) # arg 1 to values must be hash (not list assignment)
print values %{{@list}}    # success: prints 12

Если @list не содержит дублирующихся ключей (нечетных элементов), этот оператор также предоставляет способ доступа к четным или нечетным элементам списка:

@even_elements = keys %{{@list}}     # @list[0,2,4,...]
@odd_elements = values %{{@list}}    # @list[1,3,5,...]
3
ответ дан 28 November 2019 в 05:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: