Является ли трюк "my $x if 0" применимым для создания статической переменной для Perls до 5.10?

В Perl до 5.10 не существует декларации состояния.

Я столкнулся с примером создания статических переменных в этих 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?

Ответы

Ответ 1

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

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";
    }
}

Ответ 2

Поведение 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";
    }
}

Ответ 3

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

use strict;

sub add {
    my @arr;

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

my $iter = add();
$iter->() for 1..7;