Newsgroup: it.comp.www.php
Titolo: Una questione di eleganza

All'interno di un ciclo in PHP ho il frammento di codice riportato qui sotto: funziona benissimo, ma non mi pare molto elegante.
Anche mettendo le condizioni su righe diverse la leggibilità del tutto risulta penalizzata (considerate che ho accorciato nomi delle variabili/costanti/array).
Voi come lo scrivereste in modo più "pulito"?
 
if ($var1 != CON_UNO && !in_array($var2, $arPrimo) && !in_array($var3, $arSecondo)) {
    if ($var1 == CON_DUE && $var3 == TRUE) {
    }
    else {
        $contatore++;
    }
}
 
Grazie e buon lavoro a tutti


if (
     $var1 != CON_UNO &&
     !in_array($var2, $arPrimo) &&
     !in_array($var3, $arSecondo) &&
     !($var1 == CON_DUE && $var3 == TRUE)) {
         $contatore++;
     }
 
 
( "{}" dopo "if ($var1 == CON_DUE && $var3 == TRUE)" è vuoto).

Voi come lo scrivereste in modo più "pulito"?
 
Mi sembra (magari sbaglio) che CON_UNO non ti serva. Se e' diversa da CON_DUE,
 
	if ($var1 == CON_DUE) {
		if (!in_array($var2, $arPrimo)) {
			if (!in_array($var3, $arSecondo) {
				if (true != $var3) {
					$contatore++;
				}
			}
		}
 
	}
 
Se invece sono uguali:
 
	if ($var1 != CON_DUE) {
		if (!in_array($var2, $arPrimo)) {
			if (!in_array($var3, $arSecondo) {
				$contatore++;
			}
		}
	}
 
Nel caso piu' generale di tutti qui hai tre variabili, che O sono in un certo
insieme (diverso per ciascuna) oppure no - quindi, niente 'range' o cose piu'
strane - potresti scriverlo:
 
	define(VAR1_OK,	1);	define(VAR1_KO, 0);
	define(VAR2_OK,	2);	define(VAR2_KO, 0);
	define(VAR3_OK,	4);	define(VAR3_KO, 0);
	define(VAR4_OK,	8);	define(VAR4_KO, 0);
 
	$then   = VAR1_OK*in_array($var1, $insieme1)
		+ VAR2_OK*in_array($var2, $insieme2)
		+ VAR3_OK*in_array($var3, $insieme3);
 
	$if	= array(
		VAR1_KO	| VAR2_KO | VAR3_KO => 0,
		VAR1_OK	| VAR2_KO | VAR3_KO => 1,
		...
		VAR1_OK	| VAR2_OK | VAR3_OK => 0,
	);
 
	$contatore += $if[$then];
 
Il vantaggio e' che sei costretto a scrivere esplicitamente i tuoi casi e che
valori li compongono, per cui ti avvedi subito di errori di logica.
 
	$contatore	+= ItsComplicated(array(
		'vars'	=> array($var1, $var2, $var3),
		'sets'	=> array(
			function($x) {
				return in_array($x, INSIEME1),
			}
			function($x) {
				return in_array($x, INSIEME2),
			}
			function($x) {
				return in_array($x, INSIEME3),
			}
		),
		'todo'	=> array(
			0, 1, 0,
			0, 0, 0,
			1, 0
		)
	);
 
La funzione scritta nel modo sopra puo' essere testata automaticamente e puo'
perfino segnalarti alcuni errori nel passaggio dei parametri... ed accetta un
numero arbitrario di condizioni.
 
Sospetto che si veda che originariamente non era scritta in PHP <grin>
 
Leonardo
 
-- 
 
Then felt I like some watcher of the skies, when a new planet swims into his ken;
Or like stout Cortez when with eagle eyes, he star'd at the Pacific; and all his men
Look'd at each other with a wild surmise - silent, upon a peak in Darien.

 ( "{}" dopo "if ($var1 == CON_DUE && $var3 == TRUE)" è vuoto).
 
...e vuoto deve restare!
L'incremento del contatore non deve avvenire nel THEN, ma solamente nella clausola ELSE dell'ultimo IF.

@Leonardo Sarni: leggo spesso i tuoi interventi in questo gruppo e devo dire che sei una fonte di ispirazione!
A volte (come in questo caso) devo rileggere i tuoi post due/tre volte per capirne la logica, ma probabilmente è un mio problema.
 
Il mio problema era dare maggiore leggibilità al codice, ma scritto come dici tu mi sembra di andare nella direzione contraria...
 
Ad ogni modo sperimenterò il tuo metodo.
 
Grazie.


 
Proprio per questo proponevo di sostituire
if ($c1)
  {
   if ($c2)
    {}
   else
    {$contatore++;}
  }
con
 
if ($c1 && !$c2)
  {$contatore++;}
 
Unico if, stesso risultato:
"if ($c1) {} else {...}"
è uguale a
"if (!$c1) {...}

Il mio problema era dare maggiore leggibilità al codice, ma scritto come dici tu mi sembra di andare nella direzione contraria...
 
In parte e' cosi'. I primi due tentativi erano una versione "leggibile", e che
richiedeva solo di stabilire se CON_UNO e CON_DUE fossero la stessa condizione
oppure no.
 
Ma nel caso di piu' condizioni che interagiscono, tu hai il problema di sapere
"Cosa succede se A e' vera ma B e' falsa e C e' vera?", e prevedere tutti quei
casi.
 
Manutenere un sistema cosi' puo' essere difficile, specie se le condizioni non
sono li' tutte fin dall'inizio ma se ne aggiungono dopo ("Condizione speciale,
override! Se il cliente ha un fido oltre 10K euro..." "Override dell'override!
Se il cliente ha un fido oltre 10K euro, PERO' ha un ticket amministrativo..."
"Override dell'override dell'override! I ticket aperti con causali di gruppo F
non contano!" "...ma il fido deve essere almeno 50K...").
 
A quel punto rischi che si creino delle "zone d'ombra", fra le condizioni, per
cui (storia vera) se un cliente ordina 12 dame di olio ne ha 6 in omaggio, ma,
avendo in carrello 18 dame, gli regaliamo un'oliera, mentre se avesse comprato
un'oliera e 12 dame, l'oliera doveva pagarla, o cose cosi'.
 
Il problema e' che quegli incroci CI SONO DAVVERO, e almeno finche' sono pochi
conviene trovare un modo per censirli tutti: separatamente perche' non avvenga
una reazione a catena in seguito a una modifica.
