первое сообщение от новичка-пользователя. Каждый вопрос, который я гуглю, кажется, приносит мне здесь, и я всегда получаю большой ответ на то, что я ищу; таким образом, естественно это было моей первой остановкой, когда я начал обдумывать использование благословения в Perl.
Я только что вошел в ООП Perl и как раз сегодня прочитал сообщение, спрашивающее, что благословляет, делает. Я теперь понимаю, что это ссылается на скаляр/хеш/массив к объекту, 'присоединяя' его, если Вы будете.
В большинстве примеров классов я вижу в Perl, у них, кажется, нет свойств как, я привык видеть на других языках...
{ package Person;
my $property = "This is what I'm talking about :)";
sub new { ... }
...
}
Так, я создал глупый класс со свойством для наблюдения то, что произойдет. Я дал свойству значение 'NIL' сразу и затем 'Не Ноль!' в конструкторе. Используя список методов, я смог распечатать свойство, и как я ожидал, оно распечатало 'Не Ноль!'
Мой вопрос, если свойства работают то же, поскольку я ожидал, что они будут работать (объявленный в теле) затем, почему использование благословляет вообще? Каково дополнительное преимущество наличия той ссылки, когда Вы могли просто создать скаляр/хеш/массив как свойство или создать любые ссылки, Вы хотите как свойство?
Я надеюсь, что объяснил, что я пытаюсь спросить достаточно хорошо, очень зеленый с Perl :)
Ну, это не то, как вы создаете классы в 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 , чтобы узнать о стандартном способе работы.
То, что вы сделали со свойством $ в этом случае, объявлено переменной в области действия пакета "Person". Вы меняете это внутри (или снаружи, используя $ Person :: property) пакета, и любой объект, который ссылается на него, будет видеть обновленную переменную, поэтому он действует как «статический атрибут (Java)» без каких-либо реальный «частный» объем. По соглашению, скрытые вещи в Perl («частные» или «защищенные») имеют префикс подчеркивания, но, конечно, это не обязательно.
На самом деле вы не создаете новый класс, как вы указали, с ключевым словом "package"; вы можете использовать «пакет» вообще без ООП. Это просто создает отдельное «пространство имен».
Преимущество «благословения» переменной, почти всегда хеш-ссылки из того, что я видел, состоит в том, что у вас могут быть методы, как и в любом другом языке ООП. Просто не забудьте благословить все, что вы вернете в подпрограмме new {} («новый» на самом деле не зарезервированное слово; просто соглашение). Когда вы вызываете метод для «объекта» (благословенная структура данных, такая как hashref), первым аргументом метода является сама структура данных.Итак, если у вас есть хэш-ссылка с именем $ myobject, который благословлен AwesomeClass, и вы определяете метод в AwesomeClass с именем doSomethingAwesome, который должен принимать одну переменную, вам придется «сдвинуть» @_ (который является списком аргументов подпрограмму, или используйте $ _ [0]) для доступа к хэш-ссылке $ myobject. Python делает нечто подобное, и все языки так или иначе передают ссылку на объект методу. ("this" ключевое слово во многих, см. также соглашение о вызовах "thiscall")
NB: Я видел много критиков Perl в свое время, а как программист всего несколько лет. Perl - потрясающий язык, созданный очень умным лингвистом (Ларри Уоллом) и имеющий фанатичных последователей - возможно, более фанатичных в свое время, чем Ruby, но не настолько, как Дэвид Кореш). Perl делает вещи совершенно иначе, чем многие языки, но если вы посмотрите на записи кода гольфа на этом и других сайтах, вы можете ясно увидеть, что многого можно добиться с помощью очень небольшого количества Perl (никаких гарантий относительно разборчивости кода, особенно для новичков!)
Ух ... Ответ Синан на мой вкус слишком выучен, по крайней мере, после 12 часов утра :)
Так что я дам более короткий и несколько менее ответ Перли, просто для разнообразия .
Ваш вопрос на самом деле не о Perl , насколько я могу судить, и его можно так же легко сформулировать в другой форме: «Зачем вообще использовать C ++ и ООП, если в C уже есть структуры?»
Другими словами, вы, кажется, спрашиваете, в чем смысл использования парадигмы ООП.
Ответ, конечно, заключается в том, что это помогает решать определенные проблемы программной инженерии проще, чем чисто процедурное программирование. Акцент на определенных - ООП не является панацеей от каждой проблемы, как и ЛЮБАЯ техника / подход / парадигма.
Использование ООП (в виде пакетов в виде классов и благословенных хэшей в качестве объектов в Perl) позволяет вам пользоваться преимуществами наследования, полиморфизма и прочей бесполезной ООП, с которой вы, вероятно, уже достаточно хорошо знакомы из тех, кто не является Perl Опыт ООП.
Можете ли вы сделать 100% того, что сделали бы с благословенным объектом с чистой структурой данных? Абсолютно. Будет ли 100% этого кода таким же простым / коротким / читаемым / поддерживаемым кодом, которого вы можете достичь с помощью объектов? Скорее всего, нет, хотя это зависит от того, насколько хорошо ваш код ООП фактически использует преимущества, которые предоставляет ООП (кстати, я встречал предположительно код ООП (Perl, а не), который на самом деле не использовал никаких преимуществ ООП парадигму, и ее можно было бы упростить для чтения и понимания, если бы она была лишена его хрома ООП).
Значение 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