Aquí está mi método de imitar a los decoradores de python en php.
function call_decorator ($decorator, $function, $args, $kwargs) {
// Call the decorator and pass the function to it
$decorator($function, $args, $kwargs);
}
function testing ($args, $kwargs) {
echo PHP_EOL . 'test 1234' . PHP_EOL;
}
function wrap_testing ($func, $args, $kwargs) {
// Before call on passed function
echo 'Before testing';
// Call the passed function
$func($args, $kwargs);
// After call on passed function
echo 'After testing';
}
// Run test
call_decorator('wrap_testing', 'testing');
Salida:
Before testing
testing 1234
After testing
Con esta aplicación también se puede hacer algo como esto con una función anónima:
// Run new test
call_decorator('wrap_testing', function($args, $kwargs) {
echo PHP_EOL . 'Hello!' . PHP_EOL;
});
Salida:
Before testing
Hello!
After testing
Y por último se incluso puedes hacer algo cosa como esta, si te gusta.
// Run test
call_decorator(function ($func, $args, $kwargs) {
echo 'Hello ';
$func($args, $kwargs);
}, function($args, $kwargs) {
echo 'World!';
});
Salida:
Hello World!
Con esta construcción anterior, se puede pasar variables a la función interna o envoltorio, si es necesario.Aquí es que la implementación de una función interna anónima:
$test_val = 'I am accessible!';
call_decorator('wrap_testing', function($args, $kwargs){
echo $args[0];
}, array($test_val));
Se trabajará exactamente lo mismo sin una función anónima:
function test ($args, $kwargs) {
echo $kwargs['test'];
}
$test_var = 'Hello again!';
call_decorator('wrap_testing', 'test', array(), array('test' => $test_var));
Por último, si se necesita modificar la variable en el interior o bien la envoltura o el wrappie, solo necesitas pasar la variable por referencia.
Sin referencia:
$test_var = 'testing this';
call_decorator(function($func, $args, $kwargs) {
$func($args, $kwargs);
}, function($args, $kwargs) {
$args[0] = 'I changed!';
}, array($test_var));
de salida:
testing this
con referencia:
$test_var = 'testing this';
call_decorator(function($func, $args, $kwargs) {
$func($args, $kwargs);
}, function($args, $kwargs) {
$args[0] = 'I changed!';
// Reference the variable here
}, array(&$test_var));
de salida:
I changed!
Eso es todo lo que tengo por ahora, es bastante útil en muchos casos, e incluso puede envolverlos varias veces si lo desea.
Su ejemplo de Wrap_A es un poco engañoso para alguien que no sabe cómo funciona el decorador de Python, ya que su implementación de Wrap_A explícitamente hace referencia a A. La idea de decorador es que puede decorar cualquier función con ella, pero en su ejemplo claramente no podría usar 'Wrap_A' para envolver alguna otra función' B'. ¿Te importaría si edité tu pregunta para que sea una representación más precisa de qué función es la decoración? –