Как я могу использовать закрытие PHP 5.3, как мы используем блоки в Ruby - PullRequest
5 голосов
/ 25 июля 2010

Как я могу использовать PHP 5.3 Закрытия, как мы используем блоки в Ruby. Я никогда не использовал 'for' Loop в Ruby из-за использования блоков с методами 'each' 'find_all' 'inject'.

Как я могу использовать PHP 5.3 замыкания, такие как Ruby Blocks, и сказать до свидания 'for' Loops :)

Например, между {и} есть замыкание (или блокировка, или анонимная функция)

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

Я делаю это на PHP,

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

Есть ли способ сделать это способом Ruby, используя PHP Closures, поскольку PHP 5.3 поддерживает его.

Ответы [ 4 ]

5 голосов
/ 25 июля 2010

Если вы рассматриваете использование лямбда-выражений для перебора массива PHP, есть определенные функции, которые вы можете использовать для этого.Чтобы лучше проиллюстрировать это, я использовал класс-оболочку 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; }
    );

При этом замыкания в PHP не предназначены для замены цикла for и не ведут себя как блоки ruby.

2 голосов
/ 25 июля 2010

Я думаю, что array_map () и array_walk () выглядят лучше как замена RubyBlocks.

0 голосов
/ 25 июля 2010

Простой ответ: нет.Ruby не лишен циклов for (), они просто маскируют слово «for» и немного меняют синтаксис.Если вы хотите использовать замыкание, это будет просто замыкание с циклом внутри него или уродливое (и менее эффективное) рекурсивное замыкание.

И замыкания НЕ являются тем же, что и блоки.Замыкания сопоставимы с функциями в JavaScript, то есть они могут храниться в переменных и отправляться в качестве аргументов.

0 голосов
/ 25 июля 2010

Я не думаю, что анонимная функция является заменой для цикла for, и при этом я не думаю, что необходимо заменять их циклами.

Для чего это полезно, это обратный вызов.Возьмем для примера: (да, это неубранная сортировка пузырьков, но это пример)

<?php

function bubble_sort($sort_rule, $elements) {
    do {
        $swapped = false;
        for ($i = 0; $i < count($elements) - 1; $i++) {
            if ($sort_rule($elements[$i], $elements[$i + 1])) {
                $elements[$i] ^= $elements[$i + 1];
                $elements[$i + 1] ^= $elements[$i];
                $elements[$i] ^= $elements[$i + 1];
                $swapped = true;
            }
        }
    } while($swapped);
    return $elements;
}

print_r(bubble_sort(function ($a, $b) { if ($a > $b) return true; else return false; }
,array(1,6,3,7,42,-1,0,6)));
?>

Замыкания не являются заменой для циклов в процедурном языке программирования, таком как php.Конечно, если вы используете lisp или схему, они есть, но в этом нет необходимости.

Вы можете написать их таким образом, все, что вы действительно будете делать, - это создавать анонимную функцию с циклом for внутри нее.Я думаю, что рекурсия была бы просто ненужной, если бы задачу так же легко выполнить с помощью цикла for, и поэтому вы не целуетесь в циклы до свидания.

Анонимные функции также очень полезны в программировании, управляемом событиями,когда вы хотите просто определить метод обратного вызова очень быстро.

...