Pull to refresh

Comments 34

>… очень, очень, и ооочень медленные!
> Рефлексия здесь гораздо медленнее.(На 49%)
На 100000 интеракциях? Зачем автору столько?
Более того, написанный код на порядок сложнее читается чем рефлексии, и синтаксис языка тут совершенно ни при чем.
Посмотрите комментарии к статье. Там поднимаются те же вопросы, автор указывает на то, что подобные оптимизации стоит использовать там, где их никто не увидит, в классах хелперах, с обертками — UnitOfWork в doctrine, hydrator в zend.
А по поводу синтаксиса — это мне кажется крик души на счет постоянных упреков в сторону php.
Затем, что эта штука применяется в Symfony2 и ZF2 для реализации Lazy-сервисов в контейнере. И производительность должна быть очень хорошей, иначе профита было бы мало в случае массового применения в приложении.
Кхм, эта статья — результат моего обсуждения на гитхабе с Marco и Matthieu )) Но, пожалуйста, сделайте правки в тексте: Marco — это он, а то как-то неудобно даже это видеть.
По моему суть не в получении значения поля, а скорее установки, а с этим способом прийдется провернуть хак с serialize/unserialize, что медленнее
Сразу вспомнилось

#define private public

От php я далек, но если уж свойство делают закрытым, то как раз ради ограничения доступа к нему, потому что прямые обращения автор класса счел нежелательными или даже опасными. Подобные нарушения реально нужны или рассматриваются только ради спортивного интереса?
Нет. Это очень удобно при реализации ОРМ. В php есть нативные средства чтобы создавать объекты сразу из данных из БД, но они не позволяют сортировать их по объектам.
Также все это можно сделать через рефлексию. Да и судя по документации Closure::bind был придуман именно для таких целей
Интересно конечно, но выглядит как приемчики старого хакера :) Заламывать руки чтобы достучаться до того, что в общем для такого доступа не задумано. В разрезе самого орм производительность ощутимо выросла? В доке действительно пример показывает такой хитрый доступ к приватным переменным… атас. Ломают сами себя.
Лично я считаю, что все эти private и protected должны носить строго рекомендательный и справочный характер: сказываться только на подсказках, выдаваемых IDE. Объясню почему. Вот нужно, допустим, расширить класс, написанный не мной… а автор заприватил, остатся только форк делать (если не учитывать возможность подобных хаков), что нежелательно — его приходится поддерживать, сливать и т.д… Короче, если используешь private свойства (читай недокументированные функции), то будь готов, что после очередного рефакторинга, произведенного автором, твое расширение работать не будет. Почему же нельзя получить доступ к протектед извне вообще не доходит: к ним можно получить доступ просто унаследовав класс.

Короче, хороший язык должен давать возможность изменить чужой класс так, как разработчику нужно, не делая форка.

Да, и вот ещё ссылка в тему про #define private public
www.gotw.ca/gotw/076.htm
Я стараюсь все переменные делать protected, Это дает возможность наследования без проблем.
Извините, но это какой-то бред. Если автор заприватил и надо расширить, то надо либо понять почему заприватил и соответственно отрефакторить, либо (если надо экстремально быстро расширить) сделать дополнительный геттер в крайнем случае, основанный на существующих методах с задуманным автором доступом к ним. Слепые хаки доступов ведут к трудно диагностируемым проблемам там где их особо никто не ждет.
Про форки и «хорошие языки которые дают возможность изменить чужой класс..» не готов к ответу :)
Это скрипты, они не статически типизированы, они платят за это скоростью, но все это должно бы приносить дополнительные удобства, вот на пример в виде подмены обычных ассоциативных массивов объектами.
Ээ… не понял про скрипты. Выигрыш 0,3 секунды на 100к выполнений даже таких простых операций — выигрыш довольно сомнительный. Есть способы проще и эффективнее увеличить производительность. Похоже на экономию на спичках имхо. Про удобства перевода массива в объект… В чем именно это удобство?
Мне на самом деле интереснее где эту фичу ещё можно применить. Как-то сходу ничего в голову не приходит.
Я бы предложил вам, почитать Маконнела, и других интересных авторов, чтобы не писать подобное…
Представьте, например, ситуацию, когда в классе есть закрытое поле, в котором хранится количество внешних неуправляемых объектов (скажем, записей в таблице какой-нибудь БД). Весь механизм синхронизации основан на том, что поле со значением ноль считается неинициализированным. Затем это поле вскрывается и сохраняется в базу данных. Потом класс восстанавливается. Значение поля больше не актуально (внешнюю таблицу могли отредактировать), но его значение не равно нулю — поэтому механизмы синхронизации класса «спят». Если класс достаточно сложный, поиск проблемы займет немало времени.

Это все похоже на предложение редактировать содержимое баз данных с помощью обычных текстовых редакторов, чтобы обойти ограничения целостности.
#define private public
Такая конструкция, по-моему, используется для того чтобы в модуле, запускающем unit-тесты был доступ к приватным полям.
На самом деле, во многих динамических языках это хорошая практика. Доступиться до приватного свойства сложно, но можно.
И это хорошо, я считаю. Мы не настолько криворукие как могут считать разработчики либ, зачем нас искусственно ограничивать?
Это не ограничение, что доказывает возможность достучаться. Это disclamer — мол, если полез в приватное свойство, то пеняй на себя в случае чего.
Все продемонстрированные возможности достучаться явно слишком сложны. Неужели вам недостаточно просто подчеркивания в перед названием свойства, чтобы понять, что «пеняй на себя в случае чего»? Вы настолько себе не доверяете?
Все продемонстрированные возможности достучаться явно слишком сложны

Сложны для чего? Если они настолько сложны, может, проще написать автору и попросить добавить getter, или переделать самому, если лицензия позволяет?

Неужели вам недостаточно просто подчеркивания в перед названием свойства, чтобы понять, что «пеняй на себя в случае чего»? Вы настолько себе не доверяете?


Посмотрим: private — универсален, есть в большинстве языков. Автоматически отлавливается компилятором или интерпретатором. Подчерк перед названием свойства — это просто дополнительное синтаксическое соглашение.

Более того, насколько я знаю, подчерк добавляется только ради того, чтобы не занимать обычные имена: $_point вместо $point чтобы можно было делать $place->point и обрабатывать его магическими методами. Индикация тут второстепенна.

Итак: проверенный, универсальный метод с автоматическим отловом ошибок VS синтаксическое соглашение, несущее попутно со своим основным назначением роль индикатора.
Кто же победит?
> Если они настолько сложны, может, проще написать автору и попросить добавить getter,
> или переделать самому, если лицензия позволяет?
Очените пожалуйста трудозатраты и абсолютное время, которое пройдет на написание автору, его реакцию, доказательство необходимости, уговоры, что автору на самом деле нужно поддерживать еще один публичный интерфейс, ожидание когда у него до этого дойдут руки, исправления, выпуску новой версии.

В языках, где нет private это делается намного проще. На свой страх и риск, конечно, и с некоторой вероятностью, что все сломается в следующей версии.

> Посмотрим: private — универсален, есть в большинстве языков.
Я не знаю, что вы подразумеваете под универсальностью, но в большинстве более менее распространенных языков его точно нет.

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


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

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

На случай же, когда всё действительно горит, есть способы обойти private.

в большинстве более менее распространенных языков его точно нет.

Если вам не сложно, пожалуйста, приведите список этих «более-менее распространённых языков» без private.

Куда отлавливаются?

Конкретно в PHP — генерируется ошибка в случае, когда кто-то обращается извне к приватной переменной. В плюсах компилятор тоже ругается.
Проблема в том, что с замыканием мы должны знать, как называются приватные свойства (возьмем скомпилированный класс, чтобы не было доступа к исходникам, ведь если есть доступ — то никто не мешает поменять видимость прямо в них), а для этого придется использовать рефлексию.

Но вообще мне кажется, что это бага.
Посмотрите на пример в документации, для этого этот метод и задумывался
А зачем? Если они приватны значит это не просто так. Или я чего то не понимаю.
У php в ядре есть возможность создания объекта любого класса в обход вызова конструктора. Вот эта возможность бывает очень нужна. Фактически это даже не полноценные классы, это структуры. Самый простой пример — реализация ОРМ
ORM ORM, расскажи где это в ORM необходимо такое? вопрос конкретно про приватные свойства класса.
Например то, чего мы не можем поменять в объекте. То есть сохраняются в базу изменения же, так вот хочется чтобы не было метода setId, но была возможность установить этот самый id
что значит зачем? Я хочу связать объект с строкой из таблицы. Я хочу чтобы эта связь была жесткой, чтобы у программиста не было возможность установить id самостоятельно
Sign up to leave a comment.

Articles

Change theme settings