Как стать автором
Обновить

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

Для полного счастья остаются дженерики и get/set из шарпа.
И желательно выкинуть текущий union-типы и сделать их в виде отдельной сущности, например как в С++.

get/set из шарпа.

Вы про то, что надо добавить в PHP свойства? Так RFC есть на это (https://wiki.php.net/rfc/property_accessors), но во время обсуждения возникли проблемы с реализацией (переусложнение кода), так что решили пока что, если я ничего не перепутал, просто добавить readonly.

Основная проблема с такой реализацией ридонли — это невозможность делать клонирование.


Да, я в курсе что можно делать в юзерспейсе используя костыли, но простое добавление ридонли проперти на уровне приложения может поломать код где-то во внутренностях сторонней либы или фреймворка. Особенно клонировать любят сторонние либы работающие по принципам иммутабельности. Т.е. получается с одной стороны ридонли как раз хорошо подходят для иммутабельных объектов, и по идее должно хорошо работать с либами на принципах иммутабельности, но только вот внутри часто используется clone и в итоге получаем что, то что по идее должно работать вместе — работать не будет :(

во-первых, либа которая ожидает что любой объект можно клонировать по умолчанию - broken by design
во-вторых, клонирование не поломано https://3v4l.org/iH8qW#v8.1rc2, просто проперти остается рид-онли


Да я криво написал. Сам clone не сломан, но это не меняет того что этот код не будет будет работать:


    public function withX(float $x): static {
        // This implementation does not:
        $clone = clone $this;
        $clone->x = $x;
        return $clone;
    }

А это абсолютно стандартный подход в очень многих сторонних либах. Т.е. явно не хватает конструкции clone with, которую грозятся добавить в какой-то из будущих версий.


Хотя если честно с этой реализацией меньше проблем чем было с writeonce properties rfc

НЛО прилетело и опубликовало эту надпись здесь

По моему логично ожидать при клонировании объекта, что его readonly свойства уже будут иметь значения и не будут подлежать изменению. Наоборот, странно ожидать обратного. Мне кажется, что если проблемы с клонированием появляются, то readonly использован не по назначению либо где-то произошла подмена понятий.

<?php
class Koshka {
public readonly int $prop;
}
class Pushistik extends Koshka {
public readonly int $prop = "Пушистая кошка";
}

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

int "Пушистая кошка" ))

Опечатался

А зачем было придумывать новое ключевое слово "readonly"? В пыхе уже есть ключевое слово "final", которое можно было бы заюзать для этих целей.

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

1) final означает запрет переопределения дочерними элементами при наследовании (как в случае констант) или запрет наследования (как с классами). В любом случае — это работа с запретами и наследованием. У readonly никакого наследования в принципе нет.
2) Потому что значение по умолчанию означает наличие инициализации поля класса. В случае же с readonly — допускается запись только в случае инициализации поля.
2.1) Аннотации уже второй год как устаревшая конструкция. Используйте атрибуты, которые можно вешать запросто на константы.

  1. Ну то есть мы видим два разных поведения в зависимости от того, к чему применен финал - для классов одно, для методов - другое. Вполне логично, если для полей оно будет третьим.

  2. Не понял, в чем тут принципиальная разница.

  3. Атрибуты до сих пор не всеми библиотеками поддерживаются.

  1. Не согласен. И для классов, и для методов, и для констант — final предоставляет совершенно идентичное поведение: Запрет изменений в потомке. Как оно указано в родителе — так и остаётся навсегда.
  2. Да, согласен. Хотел всё свалить на блокировку записи после инициализации поля, но не подумал о том, что в пыхе так же предусмотрена и инициализация полей дефолтными значениями. Так что действительно непонятно почему запретили это поведение.
  3. Ну это проблема этих морально устаревших библиотек, разве нет? И хоть JMS (насколько я понимаю речь идёт именно про него) довольно популярен, но по-мне это оверинжинеринг. С таким же успехом можно создать класс прослойки для сериализации, отличий особо не будет, кроме того, что подобный класс будет на порядки быстрее, гибче и отделён от объекта модели. Накрайняк можно воспользоваться фракталом.
  1. Можно еще чуть обобщить, до "запрет изменений", тогда применение финала к полям впишется в ту же логику.

3. И все-таки у варианта с классами есть один существенный недостаток - придется писать много кода. По классу на каждый вариант представления + все по классу на каждую вложенную структуру. А так же решать, куда это все добро размещать и как именовать. И билдить это добро каждый раз. А чем отличается фрактал от обычного json_encode - я вообще пока не догнал.

Можно еще чуть обобщить, до "запрет изменений", тогда применение финала к полям впишется в ту же логику.

Ну если с этой стороны посмотреть, то да. Тогда подходит.


И все-таки у варианта с классами есть один существенный недостаток — придется писать много кода.

Ну не так уж и много. Деклейр, неймспейс, класс и метод — 4 строчки, плюс фигурные скобочки. С другой стороны всё становится понятнее, чище, быстрее и гибче.


А фрактал я тоже не понимаю, совершенно неудобная и непрактичная какая-то штука особо. Проще самому написать тоже самое.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории