Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use PHP 5.3 Closures like We use Blocks in Ruby

How can I use PHP 5.3 Closures like We use Blocks in Ruby. I never used 'for' Loop in Ruby due to using Blocks with 'each' 'find_all' 'inject' Methods.

How can I use PHP 5.3 Closures like Ruby Blocks and say bye-bye to 'for' Loops :)

Like Between { and } is a Closure(or Block or Anonymous Function)

fruit = %w[apple banana orange]
fruit.each { |f| print "#{f}, " }

I do it in PHP this way,

$fruit = array('apple', 'banana', 'orange');
foreach ($fruit as $f) 
{
 print "$f, "; 
}

Is there a way to do this the Ruby way using PHP Closures as PHP 5.3 supports it.

like image 546
Rohit Chauhan Avatar asked Jul 25 '10 13:07

Rohit Chauhan


People also ask

Does Ruby have closures?

In Ruby, closures include code blocks or methods that have variables linked to the scope environment. This is a sensitive topic to all developers, especially those who are adapting to the functional paradigm.

What is the difference between procs and blocks?

When using parameters prefixed with ampersands, passing a block to a method results in a proc in the method's context. Procs behave like blocks, but they can be stored in a variable. Lambdas are procs that behave like methods, meaning they enforce arity and return as methods instead of in their parent scope.

How do you use blocks in Ruby?

Ruby blocks are anonymous functions that can be passed into methods. Blocks are enclosed in a do-end statement or curly braces {}. do-end is usually used for blocks that span through multiple lines while {} is used for single line blocks. Blocks can have arguments which should be defined between two pipe | characters.

What is an example of a closure in Ruby?

In Ruby, procs and lambdas are closures.


1 Answers

If you are looking at using lambdas to iterate over a PHP array, there are certain functions that you could use to accomplish that. Better illustrate it, I used a wrapper class enum:

class enum {
    public $arr;

    function __construct($array) {
        $this->arr = $array;
    }

    function each($lambda) {
        array_walk($this->arr, $lambda);
    }

    function find_all($lambda) {
        return array_filter($this->arr, $lambda);
    }

    function inject($lambda, $initial=null) {
        if ($initial == null) {
            $first = array_shift($this->arr);
            $result = array_reduce($this->arr, $lambda, $first);
            array_unshift($this->arr, $first);

            return $result;
        } else {
            return array_reduce($this->arr, $lambda, $initial);
        }
    }

}


$list = new enum(array(-1, 3, 4, 5, -7));
$list->each(function($a) { print $a . "\n";});

// in PHP you can also assign a closure to a variable 
$pos = function($a) { return ($a < 0) ? false : true;};
$positives = $list->find_all($pos);

// inject() examples
$list = new enum(range(5, 10));

$sum = $list->inject(function($sum, $n) { return $sum+$n; });
$product = $list->inject(function($acc, $n) { return $acc*$n; }, 1);

$list = new enum(array('cat', 'sheep', 'bear'));
$longest = $list->inject(function($memo, $word) {
        return (strlen($memo) > strlen($word)) ? $memo : $word; }
    );

That being said, closures in PHP aren't meant to replace the for loop nor do they behave like ruby blocks.

like image 75
quantumSoup Avatar answered Sep 28 '22 02:09

quantumSoup