Не совсем то, но почитать стоит http://perl.plover.com/.
Ну и как писали выше ниже паттерны, они на то и паттерны, что от языка не очень зависят, если требуется конкретный пример реализации, то можете попробовать сходить к монахам.
perl_desing_patterns скорее демонстрация возможностей языка, помогающая избежать ошибок проектирования. Один из источников, указывающий как управлять сложностью архитектуры именно средствами конкретного ЯП, а не бездумного копирования GoF.
Конечно. Очень умно раздраконивать объект, а не пользоваться get/set'ми. А потом поменяется внутренние представление и твоя экономия на спичках будет никому не нужна. Или в get/set внесут дополнительную логику? Поэтому этот код в первую очередь не 'красивый', а правильный.
К тому же не заводить же по новому методу на все случаи жизни.
Это теории все, на практике если что-то нужно сделать - заводят класс, функцию и т.п. А не разводят кирпичи из set/get. В том и фишка, что это практика, которая сильно отличается от теорий как «правильно».
Поэтому этот код в первую очередь не 'красивый', а правильный.
Правильный код - краткий код. Плодение get/set ради умножения это лолкс. Если умножение используется часто только дурак не вынесет ее в функцию ради «правильности», типа как расписано в учебнике.
Или в get/set внесут дополнительную логику?
Это называется неправильное проектирование. Либо метод приватный, аля только для внутреннего использования, либо внешний. Внешний интерфейс не меняется от минора к минору. Так что, кто прав?
Не всегда, например, какой-нибудь графический виджет. Перед render нужно уставнавить в нужное состояние. Или моделька перед сохранением в базу задать новые значения (set), основываясь на предыдущих (get). Эти примеры из моего опыта. Set'еры самое логичное что можно придумать. Даже если, ввести новый слой абстракции, что бы избежать пользовательского set/get'a. Все равно он будет просто скрывать эту работу.
Это называется неправильное проектирование. Либо метод приватный, аля только для внутреннего использования, либо внешний. Внешний интерфейс не меняется от минора к минору. Так что, кто прав?
Так никто не говорит о изменение интерфейса. Я про внутрению логику работы. Если вы будете всегда благородно пользоватся set'ерами и интерфейсом, то внутренее представление можно менять как хочешь. Но если делать так
$stock->{'price'} *= 2;
то с удивлением обнаружите, что у вас нарушится состояние инварианта объекта.
Тут, наверное, у нас недопонимание. Я недоволен вышей критикой перехода
# от
$stock->{'price'} *= 2;
# к
$stock->set_price($stock->get_price() * 2);
поэтому в качестве довода привел, что set/get позволдяют сохранять инвариант объекта. Так как внутри этих методов может быть нечто большое чем $self->{a} = shift. Повторюсь, тут речь не о внешней логике, а внутреней.
Повторюсь, тут речь не о внешней логике, а внутреней.
А какой смысл во внутренней логике воротить огород, как будто модуль не ваш? :) Ладно, я ничего против подобных подходов. Просто примеры неудачные, что собственно я и хотел сказать - сайт в сабже для продвинутых и слепо следовать таким «паттернам» в перле явно не стоит.
какой смысл во внутренней логике воротить огород, как будто модуль не ваш? :)
Не совсем понял о чем вы. Я имел ввиду, то что надо пользоватся тем интерфейсом, что нам предоставлен и не лезть внутрь. Если не устраивает интерфейс, то обернуть (http://perldesignpatterns.com/?FacadePattern).
Но ситуация $obj->setX(func($obj->getX())) вполне естественна.
В очень редких случаях это удобно. Либо метод возращает данные, а в перле это может быть и массивы и хэши и т.п., либо скаляры как в примере. Так вот, в обоих случаях, ИМХО, нет смысла городить огород внутри $obj->setX( вот_тут_вот ):
$obj->setX(sub { 5 * $obj->get() + $obj->get_smth_else(); }->() );
over же
$obj->setX(5 * $obj->get() + $obj->get_smth_else());
не стоит так же буквально понимать func.