Если вы ищете конфиденциальность методов в стиле Java, то MooseX :: Privacy будет большим разочарованием. Вот что происходит с конфиденциальностью метода в стиле Java:
/* This file is called Main.java */
public class Main
{
public class MyParent
{
private String message_string ()
{
return "Message from %s\n";
}
public void print_message ()
{
System.out.printf( this.message_string(), "MyParent" );
}
}
public class MyChild extends MyParent
{
public String message_string ()
{
return "Another message from %s\n";
}
}
public static void main (String[] args)
{
Main o = new Main();
o.run();
}
public void run ()
{
MyParent c = new MyChild();
c.print_message();
}
}
Вы можете скомпилировать и запустить этот пример следующим образом:
$ javac Main.java
$ java Main
Message from MyParent
Обратите внимание на то, что произошло. Родительский класс (MyParent
) объявляет message_string()
частным методом. Дочерний класс пытается переопределить метод, но получает категорический отказ - дочерний класс вам нечего!
Теперь давайте попробуем эквивалент с Perl и MooseX :: Privacy ...
# This file is called Main.pl
use v5.14;
use strict;
use warnings;
package MyParent {
use Moose;
use MooseX::Privacy;
private_method message_string => sub {
my $self = shift;
return "Message from %s\n";
};
sub print_message {
my $self = shift;
printf($self->message_string(), __PACKAGE__);
}
}
package MyChild {
use Moose; extends qw(MyParent);
use MooseX::Privacy;
sub message_string {
my $self = shift;
return "Another message from %s\n";
}
}
my $c = new MyChild();
$c->print_message();
Мы можем запустить это так:
$ perl Main.pl
Another message from MyParent
Скажите: ВАЗ?!?!?! Разве message_string
не должно быть личным ?! Как, черт возьми, MyChild
переопределил метод в MyParent
?!
Дело в том, что MooseX :: Privacy не дает вам ничего близкого к конфиденциальности методов, реализованной в большинстве языков объектно-ориентированного программирования. MooseX :: Privacy просто сродни тому, что вы делаете в вашем методе:
die "GO AWAY!!" unless caller eq __PACKAGE__;
За исключением того, что MooseX :: Privacy увеличивает время выполнения всех вызовов ваших методов.
На самом деле, нет особых причин использовать MooseX :: Privacy. Если вам нужны частные методы, поместите их в лексические переменные. Нравится:
use v5.14;
use strict;
use warnings;
package MyParent {
use Moose;
my $message_string = sub {
my $self = shift;
return "Message from %s\n";
};
sub print_message {
my $self = shift;
printf($self->$message_string(), __PACKAGE__);
}
}
package MyChild {
use Moose; extends qw(MyParent);
sub message_string {
my $self = shift;
return "Another message from %s\n";
}
}
my $c = new MyChild();
$c->print_message();
Теперь запустим его:
$ perl Main2.pl
Message from MyParent
Аллилуйя !! У нас есть настоящий частный метод!
Итак, у вас могут быть частные методы без MooseX :: Privacy, и они работают лучше (и быстрее), чем MooseX :: Privacy.
Но как насчет частных атрибутов? Что ж, у меня есть небольшой модуль на CPAN, который может вам помочь: Lexical :: Accessor. Это небольшой инструмент, который создает для вас атрибут с хранением «наизнанку» (т.е. значение атрибута не сохраняется в благословенном хешрефе объекта) и устанавливает для него аксессоры в лексических переменных (точно так же, как частный $get_message
способ выше).
Во всяком случае, это мое мнение о MooseX :: Privacy.
person
tobyink
schedule
09.04.2014
$var
статичен, PB - нет. Кроме того, PA вообще использует Moose? Если вы не понимаете преимуществ Moose, весь вопрос спорный. - person rutter   schedule 10.04.2014PA
, чтобы сделать пример минимальным .. - person Håkon Hægland   schedule 10.04.2014