Sicuramente sono io che sbaglio, sicuramente c’è un modo migliore.
Per passare una stringa che contiene un singolo backspace” da Ruby a Javascript mediante JSON, si devono usare una fracassata (<cit.> “termine tecnico”) di backspaces.
DISCLAIMER: Seguite il mio racconto, ma solo se avete cinque minuti del vostro tempo da buttare via. Io lo riporto qui a futura memoria.
Immaginiamo di avere un oggetto con una proprietà di tipo stringa di nome “testo” e valore “testo di prova” da passare tramite JSON. Seguendo la sintassi JSON si ha:
dove string è la stringa che contiene il nome della proprietà (nel nostro caso “testo”) e value è il valore della nostra proprietà (che nel nostro caso è una stringa pari a “testo di prova”).
Da cui discende che la stringa JSON che rappresenta la serializzazione del nostro oggetto è:
{"testo":"testo di prova"}
E fin qui, nulla di nuovo o di strano.
Ma se nel valore della proprietà “testo” ci mettiamo un backslash o una doppia virgoletta o un carattere di controllo, occorre seguire la sintassi prevista:
Quindi, se modifichiamo il nostro esempio e utilizziamo come valore della nostra proprietà “Il file si trova su c:\MyApp\MyDoc.txt”, avremo la seguente stringa JSON:
{"testo":"Il file si trova su c:\\MyApp\\MyDoc.txt"}
Da notare il doppio backslash.
Per ottenere questo semplice risultato sostituiamo ogni occorrenza di backslash con una doppia backslash.
L’espressione regex per trovare tali occorrenze è:
/\\/
da notare che anche l’espressione regolare suddetta richiede un doppio backslash per cercare un singolo backslash (perché anche nelle espressioni regolari il backslash è un carattere “speciale”)
Mentre la stringa che contiene il testo da applicare in sostituzione di ogni occorrenza trovata è (tenetevi forte…):
"\\\\"
che è il modo per scrivere una stringa formata da due backslash (e questo perché in Ruby non possiamo scrivere la più semplice @”\\” che avremmo usato in C#, dove il carattere @ sta proprio ad indicare che il contenuto della stringa è quello che è, senza alcuna interpretazione).
Ma ora comincia il divertimento (si fa per dire…):
Quando andiamo ad utilizzare la stringa JSON con Javascript, magari utilizzando JQuery, con una cosa del tipo:
var json_text = '{"testo":"Il file si trova su c:\\MyApp\\MyDoc.txt"}'
var my_object = jQuery.parseJSON( json_text );
riceviamo un errore di carattere non consentito.
Il motivo è tanto semplice quanto noioso: prima di passare la stringa al parser JSON, la stringa viene interpretata e ogni doppio backslash viene interpretato (giustamente, visto che stiamo trattando una stringa javascript) come un singolo backslash, che non è un carattere consentito in una stringa JSON !!!
E la soluzione è altrettanto banale quanto inelegante: dobbiamo raddoppiare ancora una volta il numero di backslash nella stringa JSON passata a javascript (da notare che questo NON è necessario se la stringa JSON proviene da una richiesta http, ma solo se è una stringa JSON contenuta in una variabile javascript). Quindi la stringa JSON da passare a javascript è la seguente:
{"testo":"Il file si trova su c:\\\\MyApp\\\\MyDoc.txt"}
E se poi siete proprio sfortunati, come me, e lavorate con Ruby… allora avrete un’altra sopresa, che nel passaggio tra Ruby e Javascript anche Ruby prima di passare la stringa l’interpreta (giustamente, visto che una stringa ruby utilizza due backslash per rappresentarne uno). Quindi bisogna raddoppiare i backslash anche qui…
Riepilogando:
Se devo mandare un oggetto che ha come valore di stringa “c:\”, devo sostituire questo singolo, banalissimo e maledettissimo backslash con ben OTTO backslash:
That’s all folks!
posted @ martedì 25 ottobre 2011 18:06