Свойства статического класса Perl

Как я знаю, создание динамических экземпляров класса (пакета) подобно взлому синтаксиса Perl (используя "благословение" ). Perl не поддерживает ключевое слово "class"; поэтому все ограничено.

Первое ограничение Perl, которое вызывает трудности в ООП, заключается в создании статических свойств класса и статических методов класса. Любое решение?

Ответ 1

Для переменных уровня класса существуют два широко используемых подхода:

package Bar;
use strict;
use warnings;

sub new { bless {}, shift };

# (1) Use a lexical variable scoped at the file level,
# and provide access via a method.
my $foo = 123;
sub get_foo { $foo }

# (2) Use a package variable. Users will be able to get access via
# the fully qualified name ($Bar::fubb) or by importing the name (if
# your class exports it).
our $fubb = 456;

Пример использования:

use Bar;

my $b = Bar->new;
print "$_\n" for $b->get_foo(), $Bar::fubb;

Ответ 2

В этот день и в возрасте, если вы действительно хотите сделать OOP с Perl, вам будет полезно использовать объектную инфраструктуру, например Moose, которая будет помогите очистить синтаксис жестокости. Это заставит сделать OO в Perl больно намного меньше, и если вы будете использовать расширения, такие как MooseX:: Declare, это будет еще слаще.

Я не делаю много вещей OO, но я думаю, что знаю, что вы пытаетесь сделать, и я считаю, что Moose может сделать это прямо.

Ответ 3

Я нашел решение:

package test;

my $static_var = undef;

#constructor not needed

#static method to set variable
sub set_var {
    my ($value) = @_;
    $static_var = $value;
}

#static method to get variable value
sub get_var {
    return $static_var;
}

1;

Согласно http://www.stonehenge.com/merlyn/UnixReview/col46.html, не представляется возможным напрямую обращаться к этим переменным в пакете. Возможно, для доступа к ним должны быть методы get, set.

Как сказано в следующей статье:

Также нет синтаксиса, позволяющего любому другому коду, находящемуся за пределами этого кода, обращаться к этим переменным, поэтому мы можем быть уверены, что наши переменные не будут таинственно меняться.

Я действительно не знаю, прав ли этот автор.

Ответ 4

Стандартная переменная пакета ведет себя как переменная класса

package foo;

my $bar;

1;

то

$foo::bar=1;  # or whatever
$foo::bar++;
print $foo::bar, "\n";