Comments 26
Все хорошо, погуглили, пообещали, но живого примера так и не привели :)
Было:
Стало:
По-моему, стало лучше. Мне писать функцию «как есть» удобнее, чем строкой (типа «return \»\";"). Также глобальный массив не захламляется, что вообще замечательно.
public static function exec($query) {
global $args;
if(DEBUG) $start_time = array_sum(explode(" ",microtime()));
if(func_num_args() > 1) {
$args = func_get_args();
$query = preg_replace_callback(
'/:([0-9]+)/',
create_function(
'$matches',
'global $args; return "\'".sqlite_escape_string(@$args[$matches[1]])."\'";'
),
$query
);
}
self::$result = sqlite_query($query, self::$handle);
if(DEBUG) self::$sql_log[] = array(
'execution_time' => array_sum(explode(" ",microtime())) - $start_time,
'query' => $query
);
return self::$result;
}
* This source code was highlighted with Source Code Highlighter.
Стало:
public static function exec($query) {
if(DEBUG) $start_time = array_sum(explode(" ",microtime()));
if(func_num_args() > 1) {
$args = func_get_args();
$query = preg_replace_callback(
'/:([0-9]+)/',
function($matches) use ($args) {
return "'".sqlite_escape_string(@$args[$matches[1]])."'";
}
),
$query
);
}
self::$result = sqlite_query($query, self::$handle);
if(DEBUG) self::$sql_log[] = array(
'execution_time' => array_sum(explode(" ",microtime())) - $start_time,
'query' => $query
);
return self::$result;
}
* This source code was highlighted with Source Code Highlighter.
По-моему, стало лучше. Мне писать функцию «как есть» удобнее, чем строкой (типа «return \»\";"). Также глобальный массив не захламляется, что вообще замечательно.
Мне кажется что живые идеи придут в голову сами по себе, и у каждого свои. Я привел парочку примеров для ознакомления с этими прекрасными нововведениями
Осталось дописать анонимные и локальные классы и «здравствуй, java!» :-)
PS Очень рад нововведениям и тому что язык становится более удобным и расширяемым.
PS Очень рад нововведениям и тому что язык становится более удобным и расширяемым.
Да, то что лямбды, замыкания и пространства имен вводят в версии 5.3, а не 6, как планировалось изначально — не может не радовать, имхо это будет значительным шагом в развитии PHP, каким например было в свое время появление нормального ООП в PHP5, по-сравнению с куцым 4-ым. Обидно только что в обиход она войдет далеко не сразу, и попользовать новшества можно будет только на достаточно больших проектах, использующих, хотя-бы виртуальные, но уже выделенные сервера.
torag, а почему вы не рассказали про такое важное нововведение, как «пространства имён»? Очень странно, ведь этого новшества так давно ждали, и было бы неплохо рассказать о нем в этом посте.
Пост какой-то некорректный.
Во-первых, «функции первого класса» это функции, которые можно сохранять в структурах данных, возвращать из других функций, отправлять в функции как аргументы, и т.д. В общем, все то, что можно делать с обычными переменными, можно делать и с функциями первого класса.
Лямбда-функции в этом контексте это неименованные функции. То есть совсем как обычные функции, но без имени. Их можно присвоить какому-то имени, и тогда получим те функции, с которыми знаком любой программист.
Далее, замыкания это такие функции, которые выполняются *в контексте*. Например (тут JS):
// обычная функция, контекст ее — все глобальные переменные и другие функции
function fun() {
… // какой-то код, неважно какой
// а вот этой функции доступны все переменные из функции fun
// это и будет «контекстом»
function bar() {… }
// здесь вполне могут быть обращения к переменным, объявленным в fun («захваченным» функцией bar)
}
Самое интересное в замыканиях, это то, что «захваченные» переменные могут «жить» после того как функция, которая их определила, закончила свое выполнение. Поэтому на замыкания можно смотреть как на объекты (те самые, из ООП) — собственно, это они и есть.
Если кого-нибудь интересует более формальное объяснение, то советую почитать о нетипизированном лямбда-исчислении (причем не отвлекаясь на Church encoding и прочую «муть»).
Во-первых, «функции первого класса» это функции, которые можно сохранять в структурах данных, возвращать из других функций, отправлять в функции как аргументы, и т.д. В общем, все то, что можно делать с обычными переменными, можно делать и с функциями первого класса.
Лямбда-функции в этом контексте это неименованные функции. То есть совсем как обычные функции, но без имени. Их можно присвоить какому-то имени, и тогда получим те функции, с которыми знаком любой программист.
Далее, замыкания это такие функции, которые выполняются *в контексте*. Например (тут JS):
// обычная функция, контекст ее — все глобальные переменные и другие функции
function fun() {
… // какой-то код, неважно какой
// а вот этой функции доступны все переменные из функции fun
// это и будет «контекстом»
function bar() {… }
// здесь вполне могут быть обращения к переменным, объявленным в fun («захваченным» функцией bar)
}
Самое интересное в замыканиях, это то, что «захваченные» переменные могут «жить» после того как функция, которая их определила, закончила свое выполнение. Поэтому на замыкания можно смотреть как на объекты (те самые, из ООП) — собственно, это они и есть.
Если кого-нибудь интересует более формальное объяснение, то советую почитать о нетипизированном лямбда-исчислении (причем не отвлекаясь на Church encoding и прочую «муть»).
Упс, забыл закрыть } после определения bar. Сорри.
> Далее, замыкания это такие функции, которые выполняются *в контексте*. Например (тут JS):
На самом деле (во всяком случае, в JS) можно выделить две теории:
— все функции — замыкания (в виду механизма цепи скопов);
— замыкание это: функция, которая (а) — имеет «на борту» свободные переменные и (б) — переживает свой лексический контекст;
На самом деле (во всяком случае, в JS) можно выделить две теории:
— все функции — замыкания (в виду механизма цепи скопов);
— замыкание это: функция, которая (а) — имеет «на борту» свободные переменные и (б) — переживает свой лексический контекст;
> замыкание это: функция, которая (а) — имеет «на борту» свободные переменные и (б) — переживает свой лексический контекст;
Это и есть верный ответ.
> все функции — замыкания (в виду механизма цепи скопов);
Авторы ECMAscript просто сильно напутали с областью видимости. :)
Это и есть верный ответ.
> все функции — замыкания (в виду механизма цепи скопов);
Авторы ECMAscript просто сильно напутали с областью видимости. :)
> Это и есть верный ответ.
Вернее, это наиболее полное использование этой конструкции (замыкание) в JS.
> Авторы ECMAscript просто сильно напутали с областью видимости. :)
Ничего они не напутали, механизм цепи скопов работает одинаково — для вложенных и глобальных функций. Так что, эта теория (все функции — замыкания; в JS) тоже имеет право на существование, правда, здесь интерес только теоретический.
Вернее, это наиболее полное использование этой конструкции (замыкание) в JS.
> Авторы ECMAscript просто сильно напутали с областью видимости. :)
Ничего они не напутали, механизм цепи скопов работает одинаково — для вложенных и глобальных функций. Так что, эта теория (все функции — замыкания; в JS) тоже имеет право на существование, правда, здесь интерес только теоретический.
Замыкания
* Это анонимные функции
Вот, жаль, что замыкание здесь описывается как обязательно анонимная функция. Вообще, в теории, анонимная функция — лишь частный случай замыкания; замыкание может быть и именованной функцией (но не в PHP).
Так же, можно отметить, что use создает локальную копию переменной из скопа выше (в отличии, например, от Javascript). Чтобы переменная ссылалась, нужно явно передавать её в use по ссылке (либо использовать модификатор global).
Наконецто php обзавёлся фитчами функционального программирования! Очень нехватало
Вопрос: в замыканиях будет использоваться лексический или динамический скоп?
Лексический конечно
Почему это, «конечно»?
Омг. Лямбды приделали. А array_reduce в качестве initial теперь что-то кроме целых цислел принимает? (см. antilamer.livejournal.com/269560.html ).
Sign up to leave a comment.
Программирование в PHP 5.3