(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Объектно-ориентированное функциональное метапрограммирование или каррирование метода

Источник: habrahabr
3axap4eHko

Искусство каррирования
Вдохновившись статьей Еще раз о каррировании и частичном применении в PHP, в голову пришла реализация частичного применения метода, именно метода, а не функции.

Вводная часть


Изначально определение каррирования дается как преобразование функции от пары аргументов в функцию, берущую свои аргументы по одному. Это преобразование было введено М. Шейнфинкелем и Г. Фреге и получило свое название в честь Х. Карри. Давайте теперь распространим это определение и на метод. Реализация этой идеи проста как 2 байта, но дает огромный потенциал. В этом и заключается доля метапрограммирования, когда методы можно создать в так сказать run-time, причем явно не описывая тело метода.

Исходный код


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

abstract class ACurry
{
    /**
    * A curry method that returns a partial call of function
    * or a result of its execution, depending on the number
    * of parameters of the invoked method
    *
    * @param array $callback
    * @param array $args
    * @return callable
    */

    protected function curry($callback, $args = array())
    {
        return function() use($callback, $args)
        {
            $methodInfo = new ReflectionMethod(get_class($callback[0]), $callback[1]);
            if (count(array_merge($args, func_get_args())) >= $methodInfo->getNumberOfParameters()) {
                return call_user_func_array($callback, $args);
            } else {
                return $callback[0]->curry($callback, $args);
            }
        };
    }

    /**
    * Create a method $methodName by currying a method of $curryMethodName
    * with arguments $args
    *
    * @param string      $methodName
    * @param string      $curryMethodName
    * @param array       $args
    * @return ACurry
    */

    public function createMethod($methodName, $curryMethodName, $args = array())
    {
        $this->$methodName = $this->curry(array($this, $curryMethodName), $args);
        return $this;
    }

    /**
    * @param string $name
    * @param array  $args
    * @return mixed
    */

    public function __call($name, $args)
    {
        if (property_exists($this, $name) && is_callable($this->$name)) {
            return call_user_func_array($this->$name, $args);
        }
    }
}

Пример


Вот мой пример применения, он сделан по аналогии с примером товарища Bodigrim
<?php
require_once 'ACurry.php';

/**
 * A class to calculate a mass from the density and size
 */

class Masses extends ACurry{

    public function __construct(){
        /* create method to calculate mass of iron cube   */
        $this->createMethod('ironCube', 'cube', array(7.8));
    }

    /**
     * Method return a mass of subjection from density and size
     */

    public function get($density, $length, $width, $height){
        return $density * $length * $width * $height;
    }

    /**
     * Method return a mass of cube subjection from density and size
     */

    public function cube($density, $length){
        return $this->get($density, $length, $length, $length);
    }
}

$masses=new Masses();
echo $masses->ironCube(2);

В данном примере псевдометод ironCube() вычисляет массу железного куба в граммах со стороной 2 см (как известно, у железа плотность 7.8 г/см³).

Итог


Вот и получилось этакое объектно-ориентированное функциональное метапрограммирование. Конечно же, область применимости этого приема возрастет в разы, если преобразуем класс в trait, что позволит нам каррировать уже наследованные методы.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 07.08.2012 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Microsoft Office 365 Профессиональный Плюс. Подписка на 1 рабочее место на 1 год
Microsoft Office 365 Бизнес. Подписка на 1 рабочее место на 1 год
Microsoft Windows Professional 10, Электронный ключ
Microsoft 365 Business Basic (corporate)
Delphi Professional Named User
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
CASE-технологии
Программирование на Microsoft Access
Утиль - лучший бесплатный софт для Windows
Программирование на Visual Basic/Visual Studio и ASP/ASP.NET
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100