Newsgroup: it.comp.www.php
Titolo: il ruolo di un validatore

function rtrimValidate1($string) {
     if (substr($string, -1) == ' ') {// se finisce con ' '
         // aggiusto la situazione
         // (faccio qualche modifica al valore originale)
         $string = rtrim($string);
     }
 
     return $string;
}
 
function rtrimValidate2($string) {
     if (substr($string, -1) == ' ') {// se finisce con ' '
         // l'ancio l'apposita eccezione
         // e non mi prendo la responsabilità di fare aggiustamenti
         // (nessuna modifica al valore originale)
         throw new \Exception('Stringa non conforme.');
     }
 
     return $string;
}
 
Nel primo caso il validatore ha la facoltà di modificare il valore 
originale.
 
Nel secondo caso il validatore si limita solo a fare dei controlli.
Se qualcosa non è conforme lancia un'apposita eccezione, senza prendersi 
la responsabilità di modificare in alcun modo il valore originale.
 
Quindi, secondo gli standard di programmazione, quale dovrebbe essere il 
compito di un validatore?


1. Il validatore non dovrebbe restituire la stringa d'origine ma bool, altrimenti è un'altra cosa. Al suo interno può manipolare il dato anche se forse sarebbe meglio farlo esternamente, dipende dalle situazioni.
 
2. Il fatto che venga passato un parametro non valido fa parte della normalità di un validatore e non dovrebbe lanciare un'eccezione. Però anche qui dipende dalle situazioni.

 2. Il fatto che venga passato un parametro non valido fa parte della normalità di un validatore e non dovrebbe lanciare un'eccezione. Però anche qui dipende dalle situazioni.
 
In pratica dovrebbe solo verificare la validità di un valore, e di 
conseguenza restituire TRUE o FALSE?


Ricordo che stiamo ragionando su convenzioni associate ad una parola, quindi il risultato può cambiare in contesti diversi.
 
Faccio un esempio. Devo valutare che il valore $input contenga una data nel formato corretto.
 
$data = uniformaSegni($input); // converte '/' '.' ' ' in '-'  e trimma (Possiamo considerarlo simile ad un purificatore)
if(!dataCorretta($data))
{
//gestire errore
}
//uso la variabile purificata $data
 
Nella mia visione se l'errore NON può essere corretto dall'utente al volo e blocca la procedura, magari in background allora
 
$data = uniformaSegni($input); // converte '/' '.' ' ' in '-'  (Possiamo considerarlo simile ad un purificatore)
try
{
dataCorretta($data); //lancia l'eccezione
//altre istruzioni
}
catch(EccezioneValidazioneData $e)
{
throw new Exception('Messaggio errore di alto livello',5,$e);
}
 
Anche se mi pare strano che un validatore si debba scaldare tanto.
 
 
Se la data 'purificata' non viene usata nel programma a quel punto può essere un'operazione svolta nel validatore.

 Se la data 'purificata' non viene usata nel programma a quel punto può essere un'operazione svolta nel validatore.
 
Certo, se lo dici tu :D
Purtroppo faccio un po' di fatica a capirti :D

 compito di un validatore?
 
In PHP la c'è la funzione filter_var() che fa proprio questi compiti. Se
ne devi scrivere una custom, io cercherei di farla comportare come quella
nativa.
 
 
Ciao!

 Anche se mi pare strano che un validatore si debba scaldare tanto.
 
Siamo ancora in estate :D


Ma ormai il lessico italiano l'abbiamo mandato in vacanza tutto l'anno :D
Povera madrelingua :)


?
C'è un errore che non vedo?
A me sembra corretto, anche un po' aulico.
 
 
Ciao!

 compito di un validatore?
 
Secondo me:
 
- Una funzione di parsing
 
	/**
	 * @param string $s
	 * @return int
	 * @throws ParseException
	 */
	function parseInt($s){...}
 
accetta una stringa come "   +0001234  " e ritorna il dato nella
rappresentazione conveniente per il programma, per esempio int 1234. Una
eccezione viene generata se il valore non è parsabile oppure è fuori del
range per int. Il livello di tolleranza agli spazi e alle mille varianti
delle rappresentazioni dei dati va scelto qui. Altri casi classici sono
il parsing degli importi monetari "1.234,56" e il parsing delle date,
che in generale coinvolgono le preferenze dell'utente.
 
- Una funzione di validazione
 
	/**
	 * @param string $s
	 * @return boolean
	 */
	function isValidInt($s){...}
 
accetta la stringa e ritorna TRUE se il dato è parsabile oppure FALSE
se non lo è. L'implementazione più semplice di questa funzione è
chiamare il parser e vedere se lancia una eccezione. Una implementazione
specifica richiede invece il perfetto allineamento con il criterio di
tolleranza del parser, tale per cui se la validazione è ok, il parser
non darà eccezione.
 
- Una funzione di sanitizzazione
 
	/**
	 * @param T $x
	 * @return T
	 */
	function sanitizeT($x){...}
 
accetta il dato di un tipo e ritorna lo stesso tipo; se il valore è
accettabile lo ritorna tal quale, altrimenti lo modidica silentemente
per adattarlo oppure lo sostituisce completamente. Per esempio, per una
stringa si tolgono i caratteri non validi, si trimma, si tronca alla
lunghezza massima consentita; il valore int 123456789 troppo grande
per una data applicazione potrebbe ritornare forzato a un dato range
[min,max] previsto dall'applicazione.
 
- Una funzione di conversione
 
	/**
	 * @param X $x
	 * @return Y
	 * @throws CastException
	 */
	function XToY($x){...}
 
accetta un dato di tipo X e ritorna un dato di tipo Y; se la conversione
fallisce viene emessa eccezione. La funzioni di parsing sono particolari
tipi di funzioni di conversione che agiscono su stringhe.
 
- Una funzione di formattazione
 
 
	/**
	 * @param T $x
	 * @return string
	 */
	function formatT($x){...}
 
 
 
prende il dato nella sua rappresentazione interna del programma e lo restituisce
in forma di stringa. E' la funzione inversa del parsing.
 
Una soluzione sistematica per tenere insieme il codice è fare una classe per ogni
tipo specifico applicando questa ricetta (è la mia check list):
 
class T {
	static function parse($s){...}
	static function fromX($x){...}
	static function isValid($s){...}
	function toX(){...}
	function toY(){...}
	function toZ(){...}
	function format(){...}
	function __toString(){...}
}
 
 
Ovviamente, parse($s) parsa la stringa $s e ritorna un oggetto T;
fromX($x) converte $x in T;
toX() converte l'istanza di T nel valore di tipo X;
format() converte l'istanza di T in una stringa;
__toString() converte l'istanza di T nelle sua rappresentazione canonica
più comune, ed è molto utile nel debugging perché così il PHP sà
già come trasformare il dato in stringa.
 
E dato che ci siamo, nella definizione della classe conviene anche
porsi il problema dell'eventuale clonabilità (methodo __clone()),
serializzabilità (interfaccia Serializable), comparabilità equals($x),
ordinamento compareTo($x) e hashing getHash() secondo il caso. Purtroppo
per comparabilità, ordinamento e hashing il PHP standard non ha
definito delle interfacce specifiche, per cui è difficile scrivere
codice intelligente e bisogna arrangiarsi in proprio, ma questo è un
altro discorso.
 
 
Ciao,
 ___ 
/_|_\  Umberto Salsi
\/_\/  
www.icosaedro.it
 
 

 ...
 
Una funzione di filtraggio?
Per me è così:
 
function filter_dir($dir) {
	return is_dir($dir) ?
		$dir :
		false
	;
}
 
Restituisce FALSE se il valore non è valido, oppure lo stesso valore 
originale.

 originale.
 
Una funzione di filtraggio dovrebbe sempre tornare un valore usabile, o 
lanciare un'eccezione in caso di errori.
 
Una di validazione, in genere, dovrebbe tornare solo true o false.
 
In questo modo le puoi comporre.
 
Tornare tipi diversi porta ad avere casini alla fine, ed è uno dei punti 
più odiati di PHP (per esempio alcune funzioni tornano un oggetto se va 
tutto bene, false se non hanno trovato la parte da modificare, null in 
caso di errori. Puntualmente ci si dimentica di gestire uno dei casi.
 
Bye.

 lanciare un'eccezione in caso di errori.
 
http://php.net/manual/en/function.filter-var.php
 
Return Values
Returns the filtered data, or FALSE if the filter fails.
 
Mettiamoci d'accordo.


P.S. (pre-scriptum) Mi sono accorto che ho scritto uno sbrodolo
come al solito.  Chi va di fretta perché parte per le vacanze può
tranquillamente evitare :-)
 
Le origini del PHP sono umili e la barriera di ingresso per i
non-programmatori è molto bassa, consentento a tanti novizi l'ingresso
nel magico mondo del web (a me, per esempio) pur senza avere una adeguata
preparazione teorica e senza avere né il tempo né la voglia di farsela.
E' a questo genere di utilizzatori che il PHP si rivolge, ed è su questi
criteri che gli sviluppatori storici non ammettono deroghe (ne andrebbe
del successo stesso del linguaggio, dove i difetti lamentati da pochi
sono proprio i pregi apprezzati dai più). Ecco perché le funzioni di
libreria standard continuano a ignorare la disponibilità delle eccezioni
e così prevedo che sarà ancora per molto tempo, anche con PHP 8.
 
Poi però i progetti si fanno più articolati e complessi, i tempi
di debugging si allungano in modo spropositato, tenere insieme tutto
l'ambaradam diventa anche più costoso che scriverlo la prima volta,
per cui la safety non è più un concetto astratto per i manualoni di
teoria, ma diventa un imperativo per tagliare tempi e costi e mantenere
il controllo sul progetto.
 
"Mantenere il controllo sul progetto" per me vuol dire sapere sempre se
qualcosa è andato storto. Ecco perché le eccezioni sono una manna per
semplificare il programma pur mantenendo intatta la safety.
 
Premesso che io mappo sempre gli errori in ErrorException (incluso anche
gli "insignificanti" E_NOTICE che spesso rilevano eventi catastrofici, vedi
appendice 1),
 
	error_reporting(PHP_INT_MAX);
 
	function my_error_handler($errno, $message) {
		throw new ErrorException($message);
	}
	set_error_handler("my_error_handler");
 
	function my_exception_handler($e)
	{
		error_log( "Uncaught $e");
		exit(1);
	}
	set_exception_handler("my_exception_handler");
 
due sono le strategie che si possono adottare:
 
1. Ignorare del tutto le eccezioni. La scrittura del codice si semplifica
enormemente perché non è più necessario testare il valore di ritorno
della funzioni:
 
	$f = fopen("last-update-date.txt", "rb");
	$s = fread($f, 999);
	...
	fclose($f);
	$upd = DateTimeTZ::parse( trim($s) );
	echo "Last update time was: $upd";
 
Qui assumo che il file da leggere esista realmente, che sia leggible,
e che contenga una data valida parsabile da una certa mia classe
DateTimeTZ. Se qualcosa va storto nella lettura del file ho un
ErrorException; se qualcosa va storto nel parsing ho un ParseException.
 
Questa implementazione è perfetta per i programmi destinati a fare quello
che ci sia aspetta che facciano oppure muoiano nell'intento; non sono
previste mezze misure perché non sarebbero safe. Nell'esempio specifico,
se non riesco a determinare l'ultima data di aggiornamento di un certo
qualcosa, è inutile continuare perché rischierei di fare aggiornamenti
continui o non farli mai senza capire che cosa sta succedendo.
 
Il programma rimane safe perché se qualcosa va storto mi ritrovo il
messaggio di errore nei log con tanto di stack trace, per cui posso
intervenire puntualmente a correggere il problema. Intanto l'utente si
è beccato una pagina vuota o incompleta (cosa che per i programmatori
PHP è come l'aglio per i vampiri) ma siccome monitoro con regolarità i
log files, e siccome faccio in modo che siano sempre vuoti, sono sicuro
di poter risolvere rapidamente.
 
2. Gestire le eccezioni. Vuol dire catturarle con try/catch e gestirle
quando esiste un piano B da applicare, oppure quando il problema non
riguarda il programma in sé ma l'accesso a una risorsa esterna e vogliamo
dare una retroazione puntuale via interfaccia utente.
 
Nel tempo ho scoperto che sono pochi i casi in cui realmente esiste un
piano B (va già grassa se il programma ha un piano A da svolgere e lo
fa bene), per cui è inutile catturare le eccezioni per questo fine. E ho
anche scoperto che è quasi sempre inutile dare all'utente una retroazione
puntuale e tecnica del problema accaduto in qualche recesso interno del
programma, cosa che sarebbe per lui del tutto inutile.
 
Ho invece scoperto che nei rari casi in cui uso try/catch lo faccio per
trasformare una eccezione di basso livello (per esempio un ErrorException)
in un'altra di più alto livello specifica del blocco di programma,
oppure catturo l'eccezione per "rimettere a posto" le cose prima di
rilanciarla.  In definitiva, ho scoperto che il try/catch serve raramente,
e che il compito di intercettare le eccezioni spetta ai piani alti del
programma, là dove si gestire l'interfaccia utente oppure si gestisce la
logica generale del programma; è lì e solo lì che bisogna catturare
le eccezioni.  Diventa quindi fondamentale sfruttare il meccanismo di
propagazione automatico della eccezioni, cosa che non si può fare o è
estremamente difficile fare con gli altri sistemi.
 
Il tutto va naturalmente condito con un validatore statico di sorgente
capace di tracciare la propagazione delle eccezioni e capace di dire dove
si originano, dove sono gestite, dove vengono deliberatamente propagate e,
soprattutto, dove ci si è dimenticati di fare questa scelta fondamentale
tra gestione locale o propagazione. E' anche per questo che mi sono
dovuto scrivere il mio validatore statico PHPLint, con il quale si può
puntare a un livello di safety paragonabile a Java ed irraggiungibile con
qualunque altro sistema o linguaggio (neppure con C++, C# e compagnia).
"php -l" semplicemente non serve a niente.
 
Il discorso cambia completamente quando ci si affida al testing del valore
di ritorno delle funzioni. I programmatori diligenti testano il valore
di ritorno di ogni singola funzione, ma si accorgono che si tratta di una
"mission impossible" perché il codice diventa un orrore del tipo:
 
	$f = fopen(...);
	if( $f === NULL ){
		// Mo' che faccio? Bò!
		die("fopen fallito");
	}
	ecc. ecc.
 
Quando lo sbrodolo si è allungato abbastanza decide per la scrittura
concisa, che fa molto hacker:
 
	$f = fopen(...) || die(...);
 
Purtroppo non si avrà uno stack trace, per cui sarà difficile indagare
sul punto dove si è verificato il problema, mentre il codice si "sporca"
e presto passa la voglia, si rinuncia a gestire gli errori, mentre il
log file si allunga, e finalmente si opta per nascondere gli errori da
php.ini nel sito di produzione. Che poi è l'ultimo e più grave errore
da fare per qualunque cosa appena più importante del blog personale.
 
In definitiva, le funzioni che ritornano NULL, FALSE o -1 su errore,
o altre cose ancora, non sono "safe" perché se il programmatore si
dimentica di verificare il valore ritornato, il programma prosegue
ciecamente andando incontro a un destino orribile e imprevedibile:
corruzione dei dati, presentazione all'utente di ridicoli dati sballati,
corruzione del data base, crash inaspettato centinaia di righe più
avanti nel codice che è poi difficile da diagnosticare.
 
Inoltre non è possibile propagare gli errori ai piani alti del programma
ma costringe a gestirli localmente oppure rinunciare; non è possibile
avere lo stack trace; non è possibile veicolare preziose informazioni
quali il tipo di errore ed eventuali dettagli specifici che invece
un oggetto può trasportare. Tutto questo rende i programmi unsafe,
difficili e frustranti da debuggare, e allunga i tempi di rilascio.
 
 
APPENDICI
 
1. Istruzioni e funzioni che generano un "insignificante" E_NOTICE su errore
che normalmente viene spento nel "sito in produzione":
 
- GET['n'] quando il dato 'n' non c'è.
 
- unserialize() se i dati sono corrotti e non è possibile ricostruire
  il valore.
 
- Quasi tutti i metodi e funzioni di DOM, iconv e tidy danno anche
un E_NOTICE se c'è un problema; non sempre in questi casi il valore
ritornato è un FALSE o un NULL, ma spesso è semplicemente una cosa
imprevedibile perché la funzione non ha fatto quello che il programma
si aspettava.
 
- Probabilmente molti altri casi che adesso non mi vengono in mente o
non sono documentati nel manuale.


 dare una retroazione puntuale via interfaccia utente.
 
Retroazione?
In cosa consisterebbe?


Per "retroazione puntuale" intendo avvisare l'utente che c'è stato un problema
specifico al sistema, evitando inutili dettagli tecnici. Per esempio:
 
$query = "select ....";
try {
	$res = $db->query($query);
}
catch(SQLException $e){
 
	// Log issue on server, with stack trace:
	error_log("failed query: $query: $e");
 
	// User feedback:
	?>
	Siamo spiacenti, ma si è verificato un problema nel nostro
	sistema nel compiere quest'ultima operazione.  Il personale
	tecnico è stato già avvertito e sta lavorando alacremente per
	risolverlo quando prima. Ti preghiamo di riprovare più tardi.
	Grazie.
	<?php
	exit(0);
}
 
La gestione puntuale delle eccezioni dà la possibilità al programma
di loggare dettagli specifici sull'operazione in corso, come ad esempio
la query SQL che è fallita, l'identità dell'utente, ecc. Poiché i
possibili contesti di esecuzione di una operazione sono infiniti, solo
il programmatore conosce quali dettagli è opportuno loggare caso per
caso. La conoscenza del contesto in cui si è verificato l'errore aiuta
a risolverlo.
 
L'alternativa è non catturare l'eccezione e lasciare che il programma
muoia in modo naturale, e allora:
 
1. L'eccezione non gestita dal programma verrà catturata dalla funzione
my_exception_handler() del mio messaggio precedente, che a sua volta
registra l'eccezione su error log e fa un exit(1). Uno stack trace
contiene già moltissime info utili, ma a volte manca di contesto e
quindi è più difficile intervenire.
 
2. L'utente riceve un HTTP 500 "Internal server error" se non c'è stato
ancora output, altrimenti vedrà una pagina inspiegabilmente incompleta.
Di norma ogni pagina viene generata prima raccogliendo tutti i dati
necessari, e poi producendo l'output, sicché l'utente dovrebbe ottenere
un 500, che è meglio di una pagina inspiegabilmente incompleta.
 
In entrambi i casi, l'error log dirà quello che c'è da fare, con o
senza feedback puntuale all'utente, e questa è la cosa più importante.
 
Tutte queste attenzioni, naturalmente, vanno dedicate solo alle eccezioni
che coinvolgono risorse esterne al programma (connessioni di rete,
data base, file system, ecc.) e quando il programma è interattivo
(in pratica, una pagina web).
 
Non è il caso di sbattersi nel gestire eccezioni e feedback quando:
 
- Il programma è una procedura batch (o va o non va e amen).
 
- Per le eccezioni interne del programma (RuntimeException e derivate,
per esempio) che non dovrebbero mai verificarsi. L'assunto è: il mio
programma è perfetto e sa reagire alle avversità esterne, altrimenti
muore con disonore (ma con eccezione loggata, però).
 
- Siamo pagati a ore per la manutenzione del sistema, e più sono oscuri
e indecifrabili i problemi che si verificano, più tempo impiegheremo e
più ore potremo fatturare.


 Una di validazione, in genere, dovrebbe tornare solo true o false.
 
Differenze tra un filtro e un sanitizzer?

 
 
Visto che il tempo speso a scrivere "bene" o "male" è più o meno lo stesso,
meglio scrivere direttamente bene. Se il tuo scopo è fregare i clienti puoi
sempre segnare più ore di manutenzione di quante non te ne servano.
 
 
Ciao!

 caso di errori. Puntualmente ci si dimentica di gestire uno dei casi.
 
Quoto, soprattutto la parte che parla dei punti odiati. Provate a andare 
a parlate di PHP su i.l.i., vi massacrano a prescindere :D
 
In parte hanno ragione, PHP dovrebbe darsi una rinfrescata, è vero che 
con PHP7 hanno migliorato molto, ma il linguaggio sta rimanendo indietro 
rispetto ai competitor.
 
Voi che ne pensate?
 
g4b0
 
P.S.
Scusate l'OT, se il flame si accende apriamo un thread apposito =D

 
 
PHP è un linguaggio orribile.
Le alternative sono peggiori.
 
 
Ciao!

 rispetto ai competitor.
 
PHP ha un po' di rogne legacy, ma cambiare il linguaggio adesso sarebbe 
una cura peggiore del male.
 
Guarda cosa è successo con Python3 (dopo 8-9 anni ancora la gente usa 
Python2) e con Perl5 (che ha praticamente ucciso il linguaggio).
 
Il vantaggio di PHP è che ci sono decine di framework e librerie che ti 
permettono di non pensare più a quelle idosincrasie perché wrappano 
tutto in classi ed eccezioni con una API migliore.
 
PHP non sta rimanendo affatto indietro, rispetto soprattutto a Python e 
Ruby. Anzi, sta crescendo a una velocità mostruosa: tipizzazione forte, 
nuova gestione delle eccezioni, performance che crescono ad ogni 
versione, ecc.
 
Forse l'unico linguaggio dinamico che sta crescendo più velocemente è 
Javascript, ma richiede una conoscenza dei sistemi di compilazione che 
lo rende più difficile di PHP.
 
Il fatto che rimanga indietro è relativo a due fattori, IMO.
 
Il primo è il suddetto "haters gonna hate": gente che non prova nemmeno 
il linguaggio, ma non lo usa a prescindere e sconsiglia ad altri di 
usarlo. Questi tipicamente usano Js (con Node) per il web e Python per 
progetti più avanzati con magari una piccola interfaccia web.
 
Il secondo è che alcuni linguaggi compilati (Go...) stanno "rubando" 
market share ai linguaggi dinamici grazie alle prestazioni e alla 
facilità di impararli (e all'hype).
 
Il problema di entrambi è che la situazione è la stessa di PHP4: sono 
tutti emozionati dalla novità e non si accorgono che:
 
1- non tutte le librerie disponibili per PHP si trovano anche per quei 
linguaggi. Anzi, spesso non si trova proprio niente, o quello che si 
trova è molto limitato.
 
2- poca gente sa davvero usare bene le potenzialità di questi "nuovi" 
linguaggi (considero anche JS "nuovo" per via di ES6 e ES7)
 
E infine, sempre valida la massima "ci sono 2 tipi di linguaggi di 
programmazione: quelli di cui tutti si lamentano, e quelli che non usa 
nessuno".
 
Bye.

 
 
Questo purtroppo vale solo per chi programma da un po', e in più linguaggi...
 
La massima che sapevo io, quando studiavo, era "c'è un linguaggio per ogni
programmatore", visto che se ne doveva ideare uno per passare l'esame.
 
Oggi boh: i nuovi laureati mi sembrano una massa di imbecilli.
 
 
Ciao!


L'ho letto.
Il tema sulla "scelta dei linguaggi di programmazione" a seguito della ricerca di 
un programmatore è stato deviato "alla mancanza di competenza del 
programmatore non Java", al dato di fatto che un "linguaggio è da scartare se 
non ci puoi sviluppare un IDE" e per finire "se un incompetente sceglie un dato 
linguaggio di programmazione vuol dire che quel linguaggio è disastroso".
 
A mio avviso hai sbagliato nel tentare di dialogare con qualcuno che è sulla 
difensiva. Magari i singoli in altre situazioni avrebbero potuto dare contributi utili, 
ma non in quel thread. Lo dovevi capire quando quel rigurgito d'ira, 
il "terapia tapioco servlet", è stato considerato un discorso chiaro e condivisibile.

Il 03/08/2018 16:40, 
fma...@gmail.com
 ha scritto:
 
 
Già che ci troviamo, la differenza tra un filtro e un sanitizzer?


 
Per la nomenclatura della filter_var, un sanitizer è un tipo di filtro.
 
 
Ciao!

 Differenze tra un filtro e un sanitizzer?
 
La differenza "ufficiale" la trovi qui:
 
http://php.net/manual/en/filter.filters.php
 
 
Un filtro è in generale qualcosa attraverso cui i dati vengono processati.
 
Un validatore applicato al filtro torna il valore o un errore.
 
Un sanitizer modifica il valore in modo che sia usabile da un sistema
specifico (il browser, il DB, ecc.)
 
Io mi sono fatto un mindset più funzionale negli ultimi anni: un filtro
(filter in termini funzionali) fa passare un dato o meno. Un sanitizer
(map) trasforma il valore. Possono essere combinati (filter_map) per far
passare un valore e contemporaneamente trasformarlo, o bloccarlo del tutto.
 
Bye.

 il "terapia tapioco servlet", è stato considerato un discorso chiaro e condivisibile.
 
Per colpa vostra mi sono andato a cercare il thread e non vi perdonerò
mai! :P
 
E già che c'ero mi sono dato una scorsa ai thread del ng e sono contento
di non seguirlo. Mi pare l'antro della frustrazione. Gente che deve
assolutamente imporre la propria opinione conoscendo il 10% del problema.
 
E onestamente mi paiono discussioni assolutamente inutili, specialmente
riguardo quello che dovrebbe il tema del ng.
 
Bye.
 
 

 Bye.
 
Concordo.
È diventata un'area di svago, a volte programmare può essere frustrante.
Sono convinto che non abbiano gli stessi atteggiamenti sul luogo di lavoro.

 Un validatore applicato al filtro torna il valore o un errore.
 
Semmai un fltro applicato a un validatore?


Come non detto, fa caldo e ogni anno vado in avaria :)

 lavoro.
 
Anche io la penso così, anche se in passato mi è capitato di avere a che 
fare con programmatori "burberi". Probabilmente è un tratto distintivo 
della categoria, anche se fortunatamente non tutti siamo così =D
 
La cosa che fa ridere di i.l.i. è che è frequentato anche da qualche 
pensionato che trolla, viene insultato ed insulta. In effetti hai 
ragione, è un area di svago. Probabilmente chi ci perde tutto quel tempo 
non ha tanti amici "reali" ed è troppo vecchio per fb, twitter e social 
vari, per cui sfoga la sua rabbia li.
 
g4b0
 

 nessuno".
 
Eheh, vero. 
 
g4b0

 di i.l.i. sono programmatori Java che odiano il PHP.
 
I programmatori Java sono forse i primi haters della storia dei 
linguaggi di programmazione. :D
Loro avevano Sun che gli diceva che erano i migliori (e adesso hanno 
Oracle), e i poveracci che sviluppavano in C e C++ non avevano idea di 
cosa si stessero perdendo.
 
Per come la vedo io sono dinosauri entrambi. Il linguaggio è importante, 
ma l'ecosistema intorno, a partire dai package managers, è quello che fa 
la differenza. Prendi composer, npm, cargo e confrontali con maven e il 
nulla con il Makefile intorno che c'è per C/C++ (e parzialmente Go, per 
ora).
 
Bye.

 (filter in termini funzionali) fa passare un dato o meno. Un sanitizer
 
Io lo chiamerei anche checker.


Un "checker" farebbe i "check", quindi non mi sembra un buon nome per un
sanitizer.
 
 
Ciao!

 
 
Questo invece non mi trova proprio d'accordo.
 
Sia in Java che in C/C++ puoi trovare milioni in più di librerie e codici
di ogni tipo, e una libreria con interfaccia C è utilizzabile con poco
sforzo da praticamente qualsiasi linguaggio e ambiente moderno.
 
Le uniche ragioni per cui non si programma tutti in C++ è che è difficile
trovare sviluppatori decenti, i tempi di sviluppo sono di solito più
lunghi, ed essendo un linguaggio compilato (la cui compilazione è un 
processo tutt'altro che leggero) non si adatta bene alle situazioni in
cui servono solo degli scripts.
 
 
Ciao!

 sforzo da praticamente qualsiasi linguaggio e ambiente moderno.
 
Forse non mi sono spiegato bene. :)
 
In JS fai `yarn add leftpad` e lui ti calcola le dipendenze, ti scarica 
quello che ti serve, ti configura packages.json con la versione 
corretta, e ti basta `yarn serve` e compila.
 
In Rust metti `serde: "1"` in Cargo.toml sotto `[dependencies]`, dai 
`cargo install && cargo run`. No step 3.
 
In PHP+Composer sappiamo come funziona. :)
 
In Go devi comunque cercarti la libreria a mano, ma poi copi-incolli 
l'URL dentro il sorgente, una botta di `go get myapp` e te lo installa.
 
In C/C++ non c'è niente di tutto questo. Devi scaricarti la libreria a 
mano, installarla, controllare se ha dipendenze, scaricarle, 
installarle, rinse-and-repeat, poi configurare gli autotools, lanciare 
./configure che ti crea il Makefile, lanciare make.
 
Le distro Linux rendono la vita un po' più facile, ma non sono integrate 
nel linguaggio, sono una pezza messa da altri.
 
Maven non ho idea. Ho provato a usarlo una volta e non ho capito come 
funziona.
 
Mi pare stiano cercando di fare qualcosa per C++, ma credo sia in alto mare.
 
Bye.


Se hai un progetto di un mese per un team di quattro persone, far perdere
cinque minuti o un'ora ad una di queste il primo giorno, non cambia
praticamente nulla sullo schedule, anche visto che comunque leggere la
documentazione di tale liberia toglie molto più tempo. ;)
 
Certo, sarebbe meglio non doverlo fare, ma come sai rimuovere la possibilità
di poter configurare manualmente certi pezzi non è considerato accettabile
nella maggior parte degli ambienti dove si usa C++.
 
 
Ciao!

 nella maggior parte degli ambienti dove si usa C++.
 
Per quello dico che sono dinosauri. :D
Sono rimasti a uno stile di sviluppo di 20 anni fa, e secondo me la 
pagheranno nel corto-medio periodo.
 
Mi rendo conto che il sistema a microservizi è tipicamente web, e non si 
applica, per esempio, a microcontrollori o a buona parte delle app 
desktop, ma ugualmente si potrebbe applicare alla separazione dell'app 
in librerie: definisci un'API per ogni pezzo dell'app e ogni persona si 
concentra su quello.
 
Ogni pezzo è testabile per conto suo, la struttura dell'app è più 
pulita, ogni sviluppatore deve tenere in testa meno informazioni.
 
Ma senza un sistema di gestione delle dipendenze fai presto a diventare 
matto, e tendi a continuare a ragionare in monolitico.
 
Bye.

 
 
Qui si vede che non programmi in C++ da un bel po' :)
 
10 anni fa, quando ancora scrivevo principalmente in C/C++/C#, già tutti
lavoravano solo con DL, DI, e tutti i metodi di sviluppo che per il web,
all'epoca, sembravano arrivati dal futuro :D
Ma non è strano, se ci pensi: da un lato hai ingegneri preparati e dallo
altro newbies che copiano da stackexchange.
 
Quello che serve per portare a termine, in poco tempo e al massimo della
qualità, un progetto C++, sono un progettista con le palle e due/tre
programmatori coi peli. Visto che questa gente costa effettivamente tanto,
il management semplicemente decide di tagliare sulla qualità del software
finale.
Non che abbiano torto, eh, anch'io quando do fuori i lavori chiedo a
ragazzini in India.
 
 
Ciao!


Mi riferivo al filtro non al sanitier.

Peggio ancora :)
 
 
Ciao!

 ora).
 
In effetti i colleghi che si occupano di C++ spesso li vedo in difficoltà 
a caccia di bug nascosti dietro a bitmask o processi in deadlock, perchè 
in effetti lavorano ad un monolite gigantesco su cui mettono mano decine 
di sviluppatori, con tanto di kernel custom ed amenità varie. In effetti 
lo sviluppo web è decisamente più snello e moderno, almeno dal mio punto 
di vista
 
g4b0

 di vista
 
Questo succede ancora in parecchi casi anche nel backend. I problemi 
sono diversi, con linguaggi dinamici, ma il casino è lo stesso.
Non è ancora diffusissimo il concetto di spezzare i servizi.
 
Ho avuto difficoltà anche io all'inizio, ma poi quando entri 
nell'ingranaggio non riesci a farne a meno.
 
Bye.
 

 Non è ancora diffusissimo il concetto di spezzare i servizi.
 
Vero. In effetti il problema del ragionare a Microservices è che bisogna 
entrare nella forma mentis giusta, lasciandosi alle spalle il monolite.
Dopo Rust, o in concomitanza, ci faccio un pensiero.
 
Grazie per le dritte.
 
g4b0
 

 sentono tutti:(
 
Ma i FW si usano ancora, o ormai si va giù di composer (ormai ogni nuovo 
progetto è perlopiù un assemblaggio di librerie)?


Laravel per esempio è un framework che tiri giù con composer, il quale 
usa parecchie librerie open. Quindi la risposta è si, si usano ancora, ma 
passando tramite composer. Diffida da chi ti propone di scaricare uno 
zip :)
 
g4b0

 
 
Io cmq non ne ho mai usati.
Inizio a scrivere la struttura di base (un semplice 
controller/entrypoint senza complicazioni inutili) e poi via via scarico 
i vendors che servono.


Beh, fossi in te un giro su Laravel me lo farei, anche solo per 
didattica. Per esempio ha un ORM di livello (Fluent/Eloquent), se usato 
bene puoi dimenticarti la sintassi di SQL.
 
Oppure se preferisci roba più leggera puoi provare Silex, anche questo è 
un progetto molto interessante.
 
g4b0

 Qui si vede che non programmi in C++ da un bel po' :)
 
Mi dai troppo credito. :)
Non ho mai sviluppato in C++. Lo trovo troppo complesso. Ho cercato di 
impararlo più volte e non sono arrivato a niente.
 
Ho sviluppato in C per un po'.
Esperienza (recente e meno recente) ce l'ho con tutto il software 
scritto per Linux, e ho ancora gli incubi su autotools e make.
È troppo complicato sia per iniziare che per mantenere un progetto in 
crescita.
 
Come dici tu: o hai un team di senior o non vale nemmeno la pena iniziare.
 
Quello che dico io è che sul lungo termine, se non cambia qualcosa, C e 
C++ (e in un secondo tempo Java) perderanno sempre più utenti.
 
È già iniziato: praticamente tutto il nuovo software opensource per reti 
è scritto in Go. Buona parte del software con UI è scritto in JS con 
Electron.
 
Bye.

 un progetto molto interessante.
 
Credo che Silex sia stato deprecato di recente, a favore della nuova 
versione di Symfony che permette di avere un core minimale (in pratica 
quello che era Silex).
 
Io negli ultimi anni ho fatto praticamente tutto con Slim, che mette a 
disposizione praticamente solo un router e poco altro, ma si smazza 
tutta la parte di PSR-7 e può essere esteso facilmente tramite middleware.
 
Il tutto via composer.
 
La parte di routing è solitamente la più difficile da fare bene, quindi 
avere un fw che lo fa per me mi toglie molti problemi.
 
Bye.
 

 dato il pane per anni)
 
jQuery lo usiamo ancora anche noi per i siti più piccoli.
 
L'azienda è grandina. Questo team è parte di un team più grande (circa 
20 persone) che a sua volta è in un "team di team" (una cinquantina in 
tutto, tra sviluppatori, manager, QA, editors, ...).
 
Il mercato è parecchio diverso. Ci sono pochissime web-agency. Di solito 
le aziende grosse hanno il team web interno, e quelle piccole si 
affidano a piattaforme già pronte.
 
Ci si aspetta che uno sia flessibile e che conosca già, almeno un po', 
diversi framework.
 
Le web-agency che ci sono solitamente fanno anche app mobile.
 
Bye.

 avere un fw che lo fa per me mi toglie molti problemi.
 
Si, nel 2018 farlo a mano è una follia con tutto il buon codice che c'è 
in giro.
 
g4b0
 

 Le web-agency che ci sono solitamente fanno anche app mobile.
 
LOL, mi hai dato più info tu in 3 frasi che un anno di lurking di i.l.i.
 
g4b0
 

 C++ (e in un secondo tempo Java) perderanno sempre più utenti.
 
Consiglio: non scrivere mai una frase del genere su i.l.i.: vengono a 
prenderti a casa :D
 
g4b0

 piacerebbe qualcosa di più discorsivo.
 
C'è 
users.rust-lang.org
 (e 
iternals.rust-lang.org
 per le discussioni sul 
compilatore stesso).
 
Anche io avrei preferito un ng, ma questo, come forum, è abbastanza decente.
 
Bye.
 

 decente.
 
Ho visto il forum, non male, ma un ng IMO è sempre meglio.
 
g4b0
 

 C'è qualche progetto "importante", oltre a Firefox, che usa Rust?
 
https://www.rust-lang.org/en-US/friends.html
 
 
Credo che i più conosciuti siano npm e Dropbox, ma ci sono diversi 
progetti interessanti in quella lista, e ne mancano alcuni.
Per esempio mi pare che Microsoft abbia iniziato a usarlo su Azure di 
recente, e un paio di giorni fa ripgrep è entrato ufficialmente in Debian.
Io sto usando exa al posto di ls da un po'.
 
Bye.

 A livello di C/C++.
 
Beh, ho appena scoperto Rocket [1]. Se ho ben capito è l'equivalente di 
un microframework PHP, ma scritto in Rust. Una meraviglia :D
 
 
[1] 
https://rocket.rs/
 


Preso dall'entusiasmo ho inviato il post. Volevo dire, quotando quanto 
sopra, che Rust si piazzerà anche a livello di C/C++, ma di queste cose 
scritte in C/C++ non se ne vedono dai tempi del CGI.
 
g4b0

 un microframework PHP, ma scritto in Rust. Una meraviglia :D
 
Rocket è figo, ma mi pare abbia ancora bisogno della nightly del 
compilatore.
 
Un paio di giorni fa è uscito anche warp, che è basato su un concetto 
più funzionale (composizione di filtri sulla request) e che non mi 
dispiace per niente.
 
Ma appunto, il grosso è basato su hyper (che è in versione 0.12), che a 
sua volta è basato su futures (0.1) e tokio (0.3, mi pare) per l'async.
 
Sono versioni che, se uso al lavoro, mi mettono un bersaglio sulla 
schiena e mi puntano costantemente col laser. :D
 
Questo nonostante siano più stabili di un apollo server qualunque.
 
Stanno lavorando come matti per implementare tutto, ma ci vorrà ancora 
un pochino, secondo me.
 
Però le prestazioni sono spaventose. Per static file serve va oltre i 7 
milioni di richieste al secondo, e rimane sopra il milione al secondo 
per JSON:
 
https://www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=plaintext
 
 
Bye.

 per JSON:
 
Questo l'ho notato anche io, incredibile. Niente di paragonabile con il 
PHP, ma forse neanche con il C/C++. In effetti i concetti di immutabilità 
e di ownership, per quanto noiosi ad un primo apporoccio, danno una 
grossa mano dal punto di vista delle performance.
 
Quello che non ho capito è se è previsto in Rust lo sviluppo di qualche 
sorta di OOP, perchè quello che vedo è ancora abbastanza rudimentale.
 
g4b0
 
 

 sorta di OOP, perchè quello che vedo è ancora abbastanza rudimentale.
 
Perché non è, e non sarà mai, OOP.
Non aspettarti l'ereditarietà o il polimorfismo, insomma: non ci saranno 
mai.
 
Ma tutto il resto c'è: interfacce (trait) e classi abstract (sempre 
trait), composizione, generics, overload di operatori.
 
All'inizio sembra un po' limitante, ma poi ci fai la mano.
 
Bye.

 }
 
Ma invece di invocare implicitamente il metodo __toString(), non sarebbe 
più giusto invocare il metodo __debugInfo() (tramite print_r($e, true)) 
che è fatto apposta per restituire un array con i dati di debug?


Che differenza fa __debugInfo() con __toString()? A parte il fatto che
con __toString() puoi facilmente costruire stringhe composte, mentre
con __debugInfo() no.
 
Una volta definito il metodo magico __deugInfo(), come fai poi a sapere
cosa c'è *veramente* dentro a un oggetto? Gli strumenti di debugging
servono quando succedono cose inattese, per cui da var_dump() ti aspetti
di vedere cosa c'è veramente, non quello che il programmatore ha deciso
di mostrare. Usi la reflection?
 
Se poi ci aggiungi print_r, che stampa i dati in formato "human readable",
non capisci più nulla:
 
print_r(123)
print_r(123.0)
print_r("123")
 
stampano tutti la stessa cosa, così come
 
print_r("")
print_r(false)
print_r(null)
 
e non è una bella cosa ai fini diagnostici. Insomma, è da valutare,
ma dovresti argomentare.
 
 
Ciao,
 ___ 
/_|_\  Umberto Salsi
\/_\/  
www.icosaedro.it
 
 

 ma dovresti argomentare.
 
Valuterò :)