Tengo algunos métodos de "setter" en todas las clases, y por comodidad he agregado un parámetro opcional $previous
, que toma un argumento por referencia y lo rellena con el valor existente antes de reemplazarlo por el nuevo uno. Por ejemplo:Probando argumentos opcionales en PHP
public function set_value($key, $value, &$previous = null)
{
$previous = $this->get_value($key);
$this->_values[$key] = $value;
return $this;
}
Esto funciona bien; sin embargo, en algunas circunstancias, el método "getter" correspondiente consume un poco de proceso, y ejecutarlo incondicionalmente es un desperdicio. Pensé que podría probar:
if(null !== $previous)
{
$previous = $this->get_value($key);
}
Esto no funciona, sin embargo, tan a menudo la variable utilizada como argumento para $previous
no se ha definido previamente en su ámbito de aplicación, y por defecto en null de todos modos. La única solución que he hackeado a cabo es:
public function set_value($key, $value, &$previous = null)
{
$args = func_get_args();
if(isset($args[2])
{
$previous = $this->get_value($key);
}
$this->_values[$key] = $value;
return $this;
}
O, para una línea que:
if(array_key_exists(2, func_get_args()))
{
// ...
}
no me gusta el cuerpo del método siendo dependientes de los índices de argumentos (cuando parece que debería ser innecesario) ¿Hay una manera más clara de lograr lo que busco aquí?
He intentado:
if(isset($previous)){}
if(!empty($previous)){}
if(null !== $previous){}
Ni trabajo.
soluciones posibles hasta el momento:
if(func_num_args() == $num_params){}
if(array_key_exists($param_index, func_get_args())){}
// 5.4
if(isset(func_get_args()[$param_index])){}
// 5.4
if(func_num_args() == (new \ReflectionMethod(__CLASS__, __FUNCTION__))
->getNumberOfParameters()){}
@DaveRandom - Por lo tanto, algo en el área de:
define('_NOPARAM', '_NOPARAM' . hash('sha4096', microtime()));
function foo($bar = _NOPARAM)
{
// ...
}
@hoppa - caso de uso:
$obj->set_something('some_key', $some_value, $previous) // set
->do_something_that_uses_some_key()
->set_something('some_key', $previous) // and reset
->do_something_that_uses_some_key()
-> ...
En lugar de:
$previous = $obj->get_something('some_key'); // get
$obj->set_something('some_key', $some_value) // set
->do_something_that_uses_some_key();
->set_something($previous) // and reset
->do_something_that_uses_some_key();
-> ...
no Podría definir el valor por defecto para '$ previous' como FALSE (o algún valor de la" tipo "incorrecto" - entonces usted sabe que es 'nulo' que fue aprobado, pero es' FALSO' (o lo que sea) que no fue. Este método también tiene agujeros (el usuario puede pasar su valor predeterminado), pero creo que sería un enfoque decente, especialmente si convierte el valor predeterminado en una cadena aleatoria larga que es muy poco probable que esté en la variable que se pasó . – DaveRandom
@DaveRandom - El valor anterior podría ser un booleano 'false' en algunas circunstancias. Elegí 'null' por su intención semántica," ausencia de valor ". – Dan
Vea el comentario editado sobre la cadena larga aleatoria - Admito que no es un enfoque bonito o perfecto, pero es un enfoque de 99.99999% de trabajos ... – DaveRandom