Lambda Functions/Closures no PHP 5.3
August 5th, 2008 by newtonDas diversas alterações anunciadas no lançamento da Alpha 1 do PHP 5.3, a que mais me chamou a atenção foi, sem dúvidas, a implementação de “Lambda Functions/Closures“. Mais até do que a implantação de Namespaces, que foi tão discutida por aí que não deve ter causado nenhum impacto mesmo.
Se você ao ler isso, assim como eu ao ler a notícia no php.net, está se perguntando: “ok, mas o que é isso afinal?”, acho que um trecho de exemplo de código vale mais do que mil palavras:
$variavel = function () { echo "Hello World"; };
$variavel ();
Pronto. Isso é, nada mais, nada menos, do que um Hello World com “lambda function”. Você pode estar pensando que já viu isso em algum lugar e tem toda razão. Se você desenvolve JavaScript há algum tempo, provavelmente já viu esse tipo de atribuição, principalmente para adicionar uma funcionalidade a um evento em um objeto.
Assim como no JavaScript, você poderá passar parâmetros para a função. Usando mais uma vez o famoso Hello World:
$variavel = function ($string) { echo $string; };
$variavel ("Hello World");
Indo mais além, você pode definir quais variáveis de fora do escopo da função, serão utilizadas lá dentro, e têm comportamento idêntico ao dos parâmetros de uma função, isto é, elas são, na verdade, copiadas para dentro do escopo da função e, caso queira, você pode passá-las por referência, utilizando o caracter &:
$hello = "Hello";
$world = "Newton";
$variavel = function () use ($hello, &$world)
{
$hello = "Hi";
$world = " World";
echo $hello . $world; // echoa "Hi World"
};
$variavel ();
echo $hello . $world; // echoa "Hello World"
No exemplo acima, definimos as strings $hello e $world. Depois, chamamos a função, informando que usaríamos as mesmas variáveis, sendo que $world está sendo passada por referência. Ainda dentro da função alteramos as duas e exibimos na tela. Após a execução da função, exibimos novamente as variáveis $hello e $world, sendo que a primeira foi alterada apenas dentro do escopo da função e a segunda, passada por referência, sofreu alteração (incluímos o espaço ali pra quem não notou).
Muito interessante a implementação da chamada da função, que acabou ganhando aplicação em objetos, que, ao serem chamados no formato $objeto(), chama automaticamente o método mágico __invoke() da classe:
class Objeto
{
public function __invoke()
{
echo "Hello Objeto";
}
}
$objeto = new Objeto
$objeto (); // exibe na tela "Hello Objeto"
// lembro que "echo $objeto;" continuará chamando __toString()
Confesso que, a primeira vista, não consegui achar utilidade nenhuma pra isso, além de uma forma diferente de trabalhar com funções, principalmente em chamadas de callbacks (call_user_func()), onde você passaria uma variável ao invés de um array ou uma string. Porém, comentando o assunto por aí, alguns desenvolvedores se mostraram entusiasmados com a novidade. Minha recomendação é aquela padrão: use com moderação, somente em casos onde de fato for relevante.
Mais detalhes sobre lambda funcions/closures no wiki do php.net, ou ainda, no anúncio do lançamento da 5.3 alpha 1.