Используется ли трюк "my $ x if 0" для создания статической переменной для Perls до 5.10? - PullRequest
13 голосов
/ 29 января 2010

В Perl до 5.10 нет декларации "state".

Я сталкивался с примером создания статических переменных в этих Perls: my $x if 0. Условие if 0 заставляет переменную действовать как статическая переменная:

use strict; use warnings;
add() for 1..7;

sub add {
    my @arr = () if 0;

    push @arr, '+';
    print @arr, "\n";
}

печать:

+
++
+++
++++
+++++
++++++
+++++++

Соответствует ли это поведение во всех версиях Perl до 5.10?

Ответы [ 3 ]

15 голосов
/ 29 января 2010

Поведение my $x if 0 является ошибкой. Он выжил в течение длительного времени, потому что он полезен и, следовательно, используется; исправление этого сломало бы существующий код. Он совместим и поэтому может считаться пригодным для использования, но это не значит, что вы должны это делать. Эта «функция» устарела и с 5.10 выдает предупреждение:

Deprecated use of my() in false conditional

Даже если вы не можете использовать state (т. Е. Ваш код должен работать под версиями Perl до 5.10), уловка my $x if 0 - просто лень. В противном случае используйте закрытие:

{
    my $x;
    sub counter {
        $x = '1' unless defined $x;
        print $x++, "\n";
    }
}
14 голосов
/ 29 января 2010

Я всегда использовал ограничительные скобки для создания статических переменных.

add() for 1..2;       # Append to existing.
add('foo', 'bar');    # Re-initialize if args are passed.
add() for 1..2;       # Append to existing.
{
    my @arr;
    sub add {
        @arr = @_ if @_;
        push @arr, '+';
        print @arr, "\n";
    }
}
9 голосов
/ 29 января 2010

Нет, это очень отвратительно. Вместо этого используйте закрытие.

use strict;

sub add {
    my @arr;

    return sub {
        push @arr, '+';
        print @arr, "\n";
    }
}

my $iter = add();
$iter->() for 1..7;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...