Благословлять или не благословлять, который является моим вопросом!

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

Я только что вошел в ООП Perl и как раз сегодня прочитал сообщение, спрашивающее, что благословляет, делает. Я теперь понимаю, что это ссылается на скаляр/хеш/массив к объекту, 'присоединяя' его, если Вы будете.

В большинстве примеров классов я вижу в Perl, у них, кажется, нет свойств как, я привык видеть на других языках...

{ package Person;
    my $property = "This is what I'm talking about :)";

    sub new { ... }
    ...
}

Так, я создал глупый класс со свойством для наблюдения то, что произойдет. Я дал свойству значение 'NIL' сразу и затем 'Не Ноль!' в конструкторе. Используя список методов, я смог распечатать свойство, и как я ожидал, оно распечатало 'Не Ноль!'

Мой вопрос, если свойства работают то же, поскольку я ожидал, что они будут работать (объявленный в теле) затем, почему использование благословляет вообще? Каково дополнительное преимущество наличия той ссылки, когда Вы могли просто создать скаляр/хеш/массив как свойство или создать любые ссылки, Вы хотите как свойство?

Я надеюсь, что объяснил, что я пытаюсь спросить достаточно хорошо, очень зеленый с Perl :)

6
задан NiRC 11 August 2010 в 03:07
поделиться

4 ответа

Ну, это не то, как вы создаете классы в Perl.

Ваша переменная $ property определена в области пакета. Следовательно, для каждого класса будет только одна его копия, а не для каждого объекта, имеющего свою собственную копию.

Можно реализовать такой класс, используя объекты на основе хешей, долгим и трудным путем, как показано ниже:

#!/usr/bin/perl

package Person;

use strict; use warnings;

sub new {
    my $class = shift;
    my $self = {};
    bless $self => $class;

    my ($arg) = @_;
    for my $property ( qw( message ) ) {
        if ( exists $arg->{$property} ) {
            $self->$property($arg->{$property});
        }
    }
    return $self;
}

sub message {
    my $self = shift;
    return $self->{message} unless @_;
    my ($msg) = @_;
    $self->{message} = $msg;
}

package main;

my $person = Person->new({
    message => "This is what I'm talking about :)"
});

print $person->message, "\n";

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

Class :: Accessor - один из таких служебных модулей.

Для программ, для которых время запуска не является проблемой, вам следует рассмотреть Moose . Используя Moose, вы можете написать это как:

#!/usr/bin/perl

package Person;

use Moose;

has 'message' => (is => 'rw', isa => 'Str');

__PACKAGE__->meta->make_immutable;
no Moose;

package main;

my $person = Person->new({
    message => "This is what I'm talking about :)"
});

print $person->message, "\n";

Вы должны прочитать perldoc perltoot и Moose :: Manual :: Unsweetened , чтобы узнать о стандартном способе работы.

11
ответ дан 8 December 2019 в 03:38
поделиться

То, что вы сделали со свойством $ в этом случае, объявлено переменной в области действия пакета "Person". Вы меняете это внутри (или снаружи, используя $ Person :: property) пакета, и любой объект, который ссылается на него, будет видеть обновленную переменную, поэтому он действует как «статический атрибут (Java)» без каких-либо реальный «частный» объем. По соглашению, скрытые вещи в Perl («частные» или «защищенные») имеют префикс подчеркивания, но, конечно, это не обязательно.

На самом деле вы не создаете новый класс, как вы указали, с ключевым словом "package"; вы можете использовать «пакет» вообще без ООП. Это просто создает отдельное «пространство имен».

Преимущество «благословения» переменной, почти всегда хеш-ссылки из того, что я видел, состоит в том, что у вас могут быть методы, как и в любом другом языке ООП. Просто не забудьте благословить все, что вы вернете в подпрограмме new {} («новый» на самом деле не зарезервированное слово; просто соглашение). Когда вы вызываете метод для «объекта» (благословенная структура данных, такая как hashref), первым аргументом метода является сама структура данных.Итак, если у вас есть хэш-ссылка с именем $ myobject, который благословлен AwesomeClass, и вы определяете метод в AwesomeClass с именем doSomethingAwesome, который должен принимать одну переменную, вам придется «сдвинуть» @_ (который является списком аргументов подпрограмму, или используйте $ _ [0]) для доступа к хэш-ссылке $ myobject. Python делает нечто подобное, и все языки так или иначе передают ссылку на объект методу. ("this" ключевое слово во многих, см. также соглашение о вызовах "thiscall")

NB: Я видел много критиков Perl в свое время, а как программист всего несколько лет. Perl - потрясающий язык, созданный очень умным лингвистом (Ларри Уоллом) и имеющий фанатичных последователей - возможно, более фанатичных в свое время, чем Ruby, но не настолько, как Дэвид Кореш). Perl делает вещи совершенно иначе, чем многие языки, но если вы посмотрите на записи кода гольфа на этом и других сайтах, вы можете ясно увидеть, что многого можно добиться с помощью очень небольшого количества Perl (никаких гарантий относительно разборчивости кода, особенно для новичков!)

8
ответ дан 8 December 2019 в 03:38
поделиться

Ух ... Ответ Синан на мой вкус слишком выучен, по крайней мере, после 12 часов утра :)

Так что я дам более короткий и несколько менее ответ Перли, просто для разнообразия .

Ваш вопрос на самом деле не о Perl , насколько я могу судить, и его можно так же легко сформулировать в другой форме: «Зачем вообще использовать C ++ и ООП, если в C уже есть структуры?»

Другими словами, вы, кажется, спрашиваете, в чем смысл использования парадигмы ООП.

Ответ, конечно, заключается в том, что это помогает решать определенные проблемы программной инженерии проще, чем чисто процедурное программирование. Акцент на определенных - ООП не является панацеей от каждой проблемы, как и ЛЮБАЯ техника / подход / парадигма.

Использование ООП (в виде пакетов в виде классов и благословенных хэшей в качестве объектов в Perl) позволяет вам пользоваться преимуществами наследования, полиморфизма и прочей бесполезной ООП, с которой вы, вероятно, уже достаточно хорошо знакомы из тех, кто не является Perl Опыт ООП.

Можете ли вы сделать 100% того, что сделали бы с благословенным объектом с чистой структурой данных? Абсолютно. Будет ли 100% этого кода таким же простым / коротким / читаемым / поддерживаемым кодом, которого вы можете достичь с помощью объектов? Скорее всего, нет, хотя это зависит от того, насколько хорошо ваш код ООП фактически использует преимущества, которые предоставляет ООП (кстати, я встречал предположительно код ООП (Perl, а не), который на самом деле не использовал никаких преимуществ ООП парадигму, и ее можно было бы упростить для чтения и понимания, если бы она была лишена его хрома ООП).

4
ответ дан 8 December 2019 в 03:38
поделиться

Значение bless'ing объекта - это получение возможности использовать методы из определенного пакета.

package MyClass;
sub answer { my ($self)=@_; return $self->{foo} * 42; }

package main;
my $object1 = { foo => 1, bar => "\t" };
my $object2 = bless { foo => 2, bar => "\t" }, "MyClass";

$ref1 = ref $object1;        #  'HASH'
$ref2 = ref $object2;        #  'MyClass'

$answer1 = $object1->answer;     # run time error
$answer2 = $object2->answer;     # calls MyClass::answer, returns 2 * 42 = 84
5
ответ дан 8 December 2019 в 03:38
поделиться
Другие вопросы по тегам:

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