<rmcreative>

RSS

Traits в trunk PHP

26 августа 2010

Вот и traits попали в транк PHP.

Данная возможность была придумана как альтернатива множественному наследованию и mixin-ам. trait представляет собой набор PHP-кода (обычно это методы), который можно использовать в своём классе. Фактически trait — поддерживаемый на уровне языка умный copy-paste.

trait Dumper {
  public function dump($var){
    echo '<pre>'.print_r($var, true).'</pre>';
  }
}
 
class MyClass {
  use Dumper;
}
 
$myClass = new MyClass();
$myClass->dump('test');

MyClass в итоге будет выглядеть как:

class MyClass {
  public function dump($var){
    echo '<pre>'.print_r($var, true).'</pre>';
  }
}

Это самый простой случай. Более сложные и интересные вещи, такие как подмена имени метода при подключении, разрешение конфликтов, trait-ы из trait-ов, требования к классу, описаны на английском в wiki.

Комментарии RSS

  1. №2927
    White Shadow
    White Shadow 26 авг. 2010 г., 20:40:15

    Сомнительное конечно нововведение, чтото не могу придумать зачем это реально может пригодиться.

    То есть пример выше это на самом деле Dumper::dump(); и зачем trait реально сложно представить, там правда еще такие конструкции добавили

    class MyPage {
       use Counter {
         public incCnt() from inc();
         public resetCnt() from reset();
       }
       use DB {
         public connect();
         public reset();
       }
       public function inc() {
         /* next page */
       }
     }

    , где DB, Counter - классы, интересно что в данном случае происходит с переменными, они общими становятся?

  2. №2928
    stalker
    stalker 26 авг. 2010 г., 20:45:50

    Ох уж этот PHP - просто костыль на костыле .. Что мешало нормально реализовать множественное наследование раз уж задались такой идеей. По функционалу получилось похожим на C++ только с черезжопным синтаксисом как и для namespace'ов. :(

  3. №2929
    White Shadow
    White Shadow 26 авг. 2010 г., 21:15:13

    да синтаксис конечно вырви-глазный...

  4. №2930
    Erlang
    Erlang 26 авг. 2010 г., 21:23:15

    На любое нововведение всегда найдётся много хаятелей, которые просто не пытаются представить, что можно писать не только всеми принятым синтаксисом, но и альтернативным, и часто такие возможности оказываются полезными в неожиданных ситуациях.

    Ни костылей, ни ужасного синтаксиса я тут не вижу, это исключительно расширение функциональности.

  5. №2931
    stalker
    stalker 26 авг. 2010 г., 21:40:08

    @Erlang, есть общепринятный синтаксис, реализованный одинаково в различных языках программирования. В данном случае: PHP изначально реализовал только одиночное наследование, а trait - это костыль для упрощения инкапсуляции. Лучше бы сразу делали множественное наследование, т.к. идея use, переопределения методов и т.п. полностью слизана с С++. Сдается мне, что разработчики PHP недавно открыли для себя его существоване и начали коряво передирать оттуда все что можно и не нужно ..

    ЗЫ: Попробуйте писать справа-на-лево снизу-в-верх - это же так альтернативно и афигенно необходимо уметь! ;)

  6. №2932
    Scriptin
    Scriptin 26 авг. 2010 г., 22:10:30

    Вообще-то синтаксис вполне традиционнй для PHP, только новые ключевые слова. Если только наличие новых ключевых слов делает для кого-то синтаксис вырвиглазным, то возникает вопрос: почему он до этого не казался вам таковым?

    Trait'ы - не костыль, а способ вторичного использования поведения, имеющий мало общего с множественным наследованием, т.к. наследуется только поведение, т.е. функции. Ну с оговоркой о статических переменных, которые фактически добавляют состояния.

    Далее, Graft'ы - это и есть множественное наследование с несколькими оговорками:

    1. другой синтаксис, но похожий, например, на синтаксис объявление метода;

    2. во включаемом классе не может быть конструкторов с аргументами;

    3. имена членов должны быть разные, для этого ключевое слово 'from'.

    Но тут же получаем преимущества:

    1. включаемый класс моожет реализовать абстрактные методы расширяемого класса (и, конечно, наоборот тоже можно);

    2. подключаем только то, что нужно.

    Вторичное использование кода в обоих случаях (Traits, Grafts) - преимущество очевидное.

    Насчет общих переменных: в расширяемом классе видно только то, что явно указано.

    ОБЩЕЕ ПРАВИЛО ДЛЯ НЕДОВОЛЬНЫХ: НЕ НРАВИТСЯ - НЕ ЕШЬ!

  7. №2933
    Sam
    Sam 26 авг. 2010 г., 22:30:10

    stalker

    С сями, скорее всего, разработчики PHP знакомы хорошо… всё-таки на них PHP и написан. С плюсами, скорее всего, тоже. По ссылке объясняется, почему не стали реализовывать множественное наследование и mixin.

  8. №2934
    Scriptin
    Scriptin 27 авг. 2010 г., 0:19:55

    @stalker

    Покажите мне в плюсах traits или mixins на уровне синтаксиса.

    А также:

    trait - это костыль для упрощения инкапсуляции

    Где тут инкапсуляция? Я уже написал, для чего нужен trait - для повторного использования поведения, т.е. методов. Как trait упрощает инкапсуляцию? Чем такой способ инкапсуляции ПРОЩЕ, чем включение тех же самых методов методов напрямую в класс? Для меня проще включить их в класс, если они используются только в нем - так ведь меньше кода писать. Другое дело - когда код используется многократно в разных классах - например, это функции профилирования или журналирования. Но чем это проще с точки зрения инкапсуляции?

    Лучше бы сразу делали множественное наследование

    Почитайте историю происхождения языка, поймете, почему автор об этом не подумал сразу.

    т.к. идея use, переопределения методов и т.п. полностью слизана с С++

    А где они переопределяются? Я вижу, что нигде. Только переименовываются в некоторых случаях. Или вы говорите об абстрактных методах (они просто реализоваываются, но не переопределяются)?

  9. №2936
    AmdY
    AmdY 27 авг. 2010 г., 1:51:40

    Это получает что-то вроде реализации паттерна Prototype?

    Вообще, мне очень понравилось, в отличе от других ООП фишек, вопрос только насколько данных синтаксис ухудшит архитектуру и понятность кода.

  10. №2939
    White Shadow
    White Shadow 27 авг. 2010 г., 12:10:58

    @Scriptin

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

    Нововведения полезные спорю, но почему синтаксис настолько разный для use класса и use trait'са?

    достаточно легко можно предстать, конструкции с > 20 методами * 5 классов, во всех переименованы функции, и другой класс, где те же самые функции но переименованы в другом порядке и так далее.

    Про историю языка, уже 5 версия на дворе, с момента происхождения ох как много всего внедрили.

  11. №2940
    stalker
    stalker 27 авг. 2010 г., 13:26:39

    @Sam

    Если Вы про это объяснение: "To circumvent this problems multiple inheritance and Mixins have been invented. But both of them are complex and hard to understand.", то как-то по-ламерски звучит .. "Не стали потому, что оно сложно для понимания" - Страуструпа видимо не читали. :)

    @Scriptin

    "почему он до этого не казался вам таковым?" - и раньше казался. Просто чем дальше, тем уродливее он становится. Ну не возможно в язык, изначально разрабатывавшийся как шаблонизатор для Perl, впихнуть все "вкусности" современных ЯП. И отказаться от этой кривизны из-за потери совместимости со старым кодом они уже не могут ..

    "имеющий мало общего с множественным наследованием, т.к. наследуется только поведение, т.е. функции" - я вижу только два отличия: 1. statless, 2. flattenable, no runtime impact.

    "НЕ НРАВИТСЯ - НЕ ЕШЬ!" - именно по этому старые проекты остановили на PHP 5.2, а новые разрабатываем на Java/Ruby.

    "Почитайте историю происхождения языка, поймете, почему автор об этом не подумал сразу." - ничего, что Я на нем с PHP3 проекты веду и сам не раз баги коммитил? ;)

    "Покажите мне в плюсах traits или mixins на уровне синтаксиса." - простите, у меня есть более важные дела, чем кого-то в чем-то убеждать.

  12. №2941
    stalker
    stalker 27 авг. 2010 г., 13:57:38

    @Scriptin

    "Trait'ы - не костыль, а способ вторичного использования поведения, имеющий мало общего с множественным наследованием, т.к. наследуется только поведение, т.е. функции." - для этого издавна используются классы со статическими методами. Теперь для этого закрепили синтаксис на уровне самого языка - ВСЕ.

    А вообще White Shadow правильно говорит - зачем так бурно реагировать? Кому нравится - будет использовать, кому НЕ нравится - НЕ будет. Мир, дружба, жвачка :)

  13. №2942
    Scriptin
    Scriptin 27 авг. 2010 г., 15:55:34

    Я не имел целью никого обижать и оскорблять, просто КАЖДЫЙ раз, когда в каком-нибудь популярном (читай "широко используемом") языке появляется что-то новое, находятся хаятели. И складывается ощущение, что все они опытные архитекторы языков программирования и точно знают, как правильно и как неправильно (только почему-то никогда не говорят, как все-таки было бы правильно).

    @White Shadow

    но почему синтаксис настолько разный для use класса и use trait'са?

    Вот это хороший вопрос. Может, еще переделают.

    @AmdY

    Это получает что-то вроде реализации паттерна Prototype?

    По-моему этот шаблон только для клонирования объектов целиком, а не для повторного использования поведения.

  14. №2959
    Bibendi
    Bibendi 30 авг. 2010 г., 12:23:46

    Ооо, радует, что пхп пытается догнать руби)), очень этого не хватало!

  15. №5042
    nazar-pc
    nazar-pc 20 июля 2011 г., 13:19:47

    Очень радуют такие фичи. Наконец нашел время почитать доки по Traits, и по-моему теперь нет смысла от интерфейсов, Traits включают полностью функционал интерфейсов, и добавляют новые возможности. Я думаю, интерфейсы должны исчезнуть, от них не будет никакого преимущества.

  16. №7790
    Alexpts
    Alexpts 06 апр. 2013 г., 16:24:27

    Как при использовании trait добиться подсветки кода в phpStorm? При использовании Singleton примеси уже нельзя в trait описать тип @var ClassName.

  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.