Comments 26
Нормуль.
Может и пригодится.
Может и пригодится.
Кстати, еще пара забавных особенностей. К сожелению сейчас под рукой 5.3 нет, поэтому немного на память:
Работать не будет, не можем мы передавать $this, в замыкание.
Мое мнение почему так (скажу чесно в исходники не лазял, сужу только с точки зрения разработчка) — замыкания в пыхе — это что-то очень похожее на обычный класс с но с новым методом __invoke(). Класс кстати этот нам ни для создания ни для наследования не доступен. Такой вот оно, млин, замыкание…
И еще очень забавное поведение:
И еще одна большая ложка дегтя:
Так же не работает.
class Foo { public function bar() { $foobar = function($someshit) use ($this) { // ... } } }
Работать не будет, не можем мы передавать $this, в замыкание.
Мое мнение почему так (скажу чесно в исходники не лазял, сужу только с точки зрения разработчка) — замыкания в пыхе — это что-то очень похожее на обычный класс с но с новым методом __invoke(). Класс кстати этот нам ни для создания ни для наследования не доступен. Такой вот оно, млин, замыкание…
И еще очень забавное поведение:
class Foo { protected $foobar; public function bar() { $this->foobar = function($someshit) { // .. } // Выдаст фатал еррор, так как метода foobar у нас в классе нет. А обращатся мы будем к нему ;) $this->foobar(); // Тут уже будет все отлично и сработает анонимная функция. $foobar = $this->foobar; $foobar(); } }
И еще одна большая ложка дегтя:
class Foo { protected $foobar = function() { // ... } }
Так же не работает.
use ($this) — смотри wiki.php.net/rfc/closures/removal-of-this
Далее замечание по коду — $this->foobar = function($someshit) {}; — обязательно точку с запятой.
по второму фрагменту — $this->foobar->__invoke() будет работать так же, а $this->foobar(); — имхо, совершенно обоснованно не будет.
protected $foobar = function() {}; — также не будет работать по понятным причинам: при присваивании начальных значений членам класса возможно использовать лишь константы.
«замыкания в пыхе — это что-то очень похожее на обычный класс с но с новым методом __invoke()» — не совсем верно понимаете. Замыкание — не класс, а объект встроенного класса Closure, у которого, действительно, есть метод __invoke(). Но значение этого метода в том, что он — т. н. «магический», т. е. вы можете написать:
Т. е. с этой точки зрения, замыкание — частный случай класса, реализующего магический метод __invoke().
Далее замечание по коду — $this->foobar = function($someshit) {}; — обязательно точку с запятой.
по второму фрагменту — $this->foobar->__invoke() будет работать так же, а $this->foobar(); — имхо, совершенно обоснованно не будет.
protected $foobar = function() {}; — также не будет работать по понятным причинам: при присваивании начальных значений членам класса возможно использовать лишь константы.
«замыкания в пыхе — это что-то очень похожее на обычный класс с но с новым методом __invoke()» — не совсем верно понимаете. Замыкание — не класс, а объект встроенного класса Closure, у которого, действительно, есть метод __invoke(). Но значение этого метода в том, что он — т. н. «магический», т. е. вы можете написать:
class Foo { function __invoke() { //.. } } $foo = new Foo(); $foo();// вызывается $foo->__invoke();
Т. е. с этой точки зрения, замыкание — частный случай класса, реализующего магический метод __invoke().
use ($this) — смотри wiki.php.net/rfc/closures/removal-of-this
Читал, смотрел. Собственно
Далее замечание по коду — $this->foobar = function($someshit) {}; — обязательно точку с запятой.
не придирайтесь, не для компилятора пишу ;)
$this->foobar(); — имхо, совершенно обоснованно не будет.
Имхо совершенно необоснованно не будет. Собственно про $this и упомянул тут, потому как врядли кто подумает делать анонимную функцию статическую, а вот передавать $this — захочется очень и очень многим.
замыкания в пыхе — это что-то очень похожее на обычный класс с но с новым методом __invoke()» — не совсем верно понимаете. Замыкание — не класс, а объект встроенного класса Closure, у которого, действительно, есть метод __invoke().
Можно я попридираюсь? :) Замыкания — это объект класса? Круто. Может быть все такие замыкания — это объекты класса встроенного класса Closure с методом __invoke, который доступен нам, плюс рюшечки в виде use?
Читал, смотрел. Собственно
Далее замечание по коду — $this->foobar = function($someshit) {}; — обязательно точку с запятой.
не придирайтесь, не для компилятора пишу ;)
$this->foobar(); — имхо, совершенно обоснованно не будет.
Имхо совершенно необоснованно не будет. Собственно про $this и упомянул тут, потому как врядли кто подумает делать анонимную функцию статическую, а вот передавать $this — захочется очень и очень многим.
замыкания в пыхе — это что-то очень похожее на обычный класс с но с новым методом __invoke()» — не совсем верно понимаете. Замыкание — не класс, а объект встроенного класса Closure, у которого, действительно, есть метод __invoke().
Можно я попридираюсь? :) Замыкания — это объект класса? Круто. Может быть все такие замыкания — это объекты класса встроенного класса Closure с методом __invoke, который доступен нам, плюс рюшечки в виде use?
Не совсем понял вашу последнюю фразу. Тем не менее, я уверен в своих словах на 100%. Замыкание — объект встроенного класса Closure, не более и не менее. А «рюшечки в виде use» — всего лишь syntax sugar (пусть и очень удобный).
$ php -r 'var_dump(function(){});' object(Closure)#1 (0) { }
Тем не менее, я уверен в своих словах на 100%. Замыкание — объект встроенного класса Closure, не более и не менее.
Я про него и говорил. Правда класс с которым мы ничего не можем и сделать — не считаю обычным ;)
А «рюшечки в виде use» — всего лишь syntax sugar (пусть и очень удобный).
use с __invoke работает? Как-то не довелось попробовать…
Я про него и говорил. Правда класс с которым мы ничего не можем и сделать — не считаю обычным ;)
А «рюшечки в виде use» — всего лишь syntax sugar (пусть и очень удобный).
use с __invoke работает? Как-то не довелось попробовать…
Ничего не понимаю. Как это «класс с которым мы ничего не можем и сделать»? А $closure->__invoke() — это разве «ничего»? Или вы о том, что мы объект Closure не можем создать, используя new Closure()?
И вопроса я тоже не понял — насчет «работает ли use с __invoke».
И вопроса я тоже не понял — насчет «работает ли use с __invoke».
new Closure; class MyClosure extends Closure {} — все это и еще кучу других вещей мы не можем с ним сделать, так что смысла от того, что это класс — немного.
$foo = function($bar) use($foobar) {}
Как такую же чтуку провернуть c __invoke?
$foo = function($bar) use($foobar) {}
Как такую же чтуку провернуть c __invoke?
closure в пыхе это все-же спец-синтаксис ;) а реализация такая для максимальной совместимости, могла быть и другая, но имхо эта неплохая… за что эту реализацию можно любить так вот за это:
function addOnRequest(Closure $callback)
{
…
}
имхо это вещь по сравнению с притянутым за уши «старым» подходом с псевдо-типом callback, который может быть и строкой и массивом и реальным калбеком от create_function… но старый код нужно будет переписать :)
function addOnRequest(Closure $callback)
{
…
}
имхо это вещь по сравнению с притянутым за уши «старым» подходом с псевдо-типом callback, который может быть и строкой и массивом и реальным калбеком от create_function… но старый код нужно будет переписать :)
function addOnRequest(Closure $callback)
{
$this->splObjectStorage->attach($callback);
return $this;
}
А? по моему очень даже :)
{
$this->splObjectStorage->attach($callback);
return $this;
}
А? по моему очень даже :)
Очень-очень ;) Единственное что смущает, один вопрос — на обычный класс с __invoke ругаться будет?
ес-но… все чОтко
Эх, а вот это уже плохо.
чем, по моему это замечательно, типизация она на то и типизация, что-бы было «чОтко» ;)
Тем, что __ivoke — это не «вести себя как замыкание», а просто «прикинуться функцией».
именно, а теперь подумайте что такое замыкание, зачем оно нужно, и что значит для объекта в глобальном контексте «вести себя как замыкание»
Я знаю что такое замыкание и зачем оно нужно ;)
Я о том, что все таки реализация какая-то для меня немного неясная — есть класс Closure — который, мы трогать не можем, кроме как в тайпхинтинге — есть анонимная функция\замыкание с одной стороны. И есть возможность сделать практически тоже самое с помощью меджик метода __invoke:
Я о том, что все таки реализация какая-то для меня немного неясная — есть класс Closure — который, мы трогать не можем, кроме как в тайпхинтинге — есть анонимная функция\замыкание с одной стороны. И есть возможность сделать практически тоже самое с помощью меджик метода __invoke:
class Foobar { function foo(Closure $closure) { $closure(); } function bar(SomeSlassWithInvoke $closure) { $closure(); } } Но это совершенно разные механизмы, нет, конечно это и в мануале ихнем написано - что с помощью этой чтуки объект просто прикидываеца функцией. Но вот народ воспринимает это немножко по другому...
Насчет «new Closure; class MyClosure extends Closure {}» — это поведение вовсе не уникально:
ну и насчет __invoke (если я вообще правильно понял, о чем речь)
final class MyClass { private function __construct(){} }
ну и насчет __invoke (если я вообще правильно понял, о чем речь)
$bar = 1; $foo = function($x) use ($bar){ echo $bar."-".$x."\n"; }; $foo(2);// prints 1-2 $foo->__invoke(2);// prints 1-2
по последнему примеру, а вот за это я люблю пых, в мане хрен знает с какой версии написано — константы и дефолтные значения только скаляры (по ману — статические значения) и не ипет. (а Closure это таки да объект класса)
как только можно будет задавать не скаляры в качестве дефолтных значений так ваш пример думается сразу заработает
как только можно будет задавать не скаляры в качестве дефолтных значений так ваш пример думается сразу заработает
ололо, в питоне это все уже сто лет работает, т.к. там изначально функции — first class citizens
(можно начинать минусовать...)
создается впечатление, что многие новые фишки пхп — чистой воды маркетинг
(можно начинать минусовать...)
создается впечатление, что многие новые фишки пхп — чистой воды маркетинг
маркетинг? Мне каежтся что язык просто начинает облагораживаться…
т.е. питон это один большой маркетинг?
нет, я имел в виду, что в питоне эти вещи работают уже много лети, причем, как им положено в теории, а в пхп они работают через костыли и подпорки… по этому я заключаю, что их добавили лишь для того, чтоб добавить пару строк в пресс-релизе, подогреть угасающий интерес, ведь практической пользы едва ли больше нуля
Что именно в PHP работает через костыли и подпорки, думается у Вас предвзятое мнение, пописал и на пайтоне и на джаве, да, напрямую эти языки сложно сравнивать и не нужно, каждому нравится что-то, но мое сердце принадлежит пыху… а нововведения очень крутые на самом деле, ради фана сел переписывать свой велосипед на 5.3, конечно результат уже слабо похож на пых но многие вещи стали очень красивыми лаконичными и строгими («строгость форм» это то, кстати, что мне очень нравилось в джаве но очень не хватало в питоне)
ну то же use(...) в объявлении лямбды — есть костыль… В питоне (да что там говорить, даже в js) автоматически захватывается весь outer scope.
Можно полюбопытствовать, о какой строгости идет речь? По моему таки питон строже (а уж жава и подавно), например в питоне вы не сделаете '1' + 2 а пхп — легко, только грошь цена той легкости, т.к. это только провоцирует баги.
Можно полюбопытствовать, о какой строгости идет речь? По моему таки питон строже (а уж жава и подавно), например в питоне вы не сделаете '1' + 2 а пхп — легко, только грошь цена той легкости, т.к. это только провоцирует баги.
Sign up to leave a comment.
PHP, Closures, use & references