Mam kilka metod "ustawiania" na różnych klasach, a dla wygody dodałem opcjonalny parametr $previous
, który pobiera argument przez odniesienie i zapełnia go istniejącą wartością przed zastąpieniem go nowymi jeden. Na przykład:Testowanie opcjonalnych argumentów w PHP
public function set_value($key, $value, &$previous = null)
{
$previous = $this->get_value($key);
$this->_values[$key] = $value;
return $this;
}
To działa dobrze; jednak w niektórych okolicznościach odpowiednia metoda "getter" jest nieco procesochłonna, a jej bezwarunkowe działanie jest marnotrawstwem. Pomyślałem mogłem przetestować:
if(null !== $previous)
{
$previous = $this->get_value($key);
}
ta nie działa jednak, jak często zmienna przekazywana jako argument za $previous
nie został wcześniej zdefiniowany w jego zakres, a domyślnie i tak null. Jedynym rozwiązaniem, jakie włamał się to:
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;
}
Albo do jednej linii to:
if(array_key_exists(2, func_get_args()))
{
// ...
}
Nie lubię ciało sposób jest uzależnione od indeksów argument (kiedy go wydaje się, że powinno być niepotrzebne) Czy istnieje lepszy sposób, aby osiągnąć to, co chcę tutaj?
Próbowałem:
if(isset($previous)){}
if(!empty($previous)){}
if(null !== $previous){}
Ani pracy.
Możliwe rozwiązania dotąd:
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 - Tak, coś w obszarze:
define('_NOPARAM', '_NOPARAM' . hash('sha4096', microtime()));
function foo($bar = _NOPARAM)
{
// ...
}
@hoppa - przypadek użycia:
$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()
-> ...
Zamiast:
$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();
-> ...
nie można zdefiniować wartość domyślną dla '$ previous' jako' FALSE (lub jakąś wartość z " wrong "type) - wtedy wiesz, że jest" null ", który został przekazany, ale jest to" FALSE "(lub cokolwiek innego), nie było. Ta metoda ma również dziury (użytkownik może przekazać wartość domyślną), ale myślę, że byłoby to przyzwoite podejście - szczególnie jeśli ustawisz domyślną wartość długiego losowego ciągu, który jest bardzo mało prawdopodobny w zmiennej, która została przekazana . – DaveRandom
@DaveRandom - poprzednia wartość może być boolowskim 'false' w niektórych okolicznościach. Wybrałem 'null' dla semantycznego zamiaru" braku wartości ". – Dan
Zobacz edytowany komentarz na temat długiego losowego ciągu - Przyznaję, że to nie jest piękne lub nieskazitelne podejście, ale to działa 99.99999% podejście ... – DaveRandom