(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, что позволит нам каррировать уже наследованные методы.

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


 Распечатать »
 Правила публикации »
  Обсудить материал в конференции Embarcadero »
Обсудить материал в конференции Microsoft »
Обсудить материал в конференции Дизайн, графика, обработка изображений »
Написать редактору 
 Рекомендовать » Дата публикации: 07.08.2012 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Delphi Professional Named User
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год.
Microsoft Office для дома и учебы 2019 (лицензия ESD)
Microsoft Office 365 для Дома 32-bit/x64. 5 ПК/Mac + 5 Планшетов + 5 Телефонов. Подписка на 1 год.
Enterprise Connectors (1 Year term)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
CASE-технологии
Программирование на Microsoft Access
Все о PHP и даже больше
Новости мира 3D-ускорителей
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
Обсуждения в форумах
Пишу программы на заказ для студентов (253)
Пишу для студентов на с, с++, паскаль в средах ms visual studio, qt, builder, borland c, delphi....
 
Разработка программ базы данных (59)
Написание прикладных компьютерных программ (базы данных) на заказ. Разработка корпоративных...
 
Выбор лучшего онлайн казино (1)
Очень важным критерием для составления рейтинга являются честные отзывы клиентов о казино. Люди...
 
Решение задач на оптимизацию с помощью MS Excel (5)
Zdravstvuyte, ya pro4itala danniy material, no ne smogla ponat kakie formuli ispolzovalis v...
 
Актуальное зеркало БК Лигаставок (3)
Актуальное зеркало букмекерской конторы Лигаставок https://superbet.guru/bk-ligastavok-mirror/...
 
 
 



    
rambler's top100 Rambler's Top100