From amijaresp at gmail.com Thu Mar 6 07:47:38 2014 From: amijaresp at gmail.com (Alberto Mijares) Date: Thu, 6 Mar 2014 11:17:38 -0430 Subject: [caracas-pm] Evaluar null en JSON Message-ID: Hola lista: Me est? ocurriendo algo muy extra?o y por eso consulto con ustedes. Tengo un script que consulta un webservice. Este devuelve un paquete JSON. Aunque es un error que debe solucionar el desarrollador del webservice, a veces me est? devolviendo valores null. Mientras eso se soluciona de aquel lado, yo necesito manejar la excepci?n. Entonces tengo, despu?s de inicializar mi objeto JSON y todo eso: for (@{$json->{lista}}) { my $valor; defined($_->{valor}) ? $valor = $_->{valor} : $valor = 'INDEFINIDO'; } Pero ocurre que siempre $valor = 'INDEFINIDO', y no siempre el valor en el JSON es null. Se supone que un valor null en JSON se transforma en undef, ?no es as?? Gracias por sus observaciones y sugerencias. Saludos Alberto Mijares From ait at p2ee.org Thu Mar 6 08:22:05 2014 From: ait at p2ee.org (Alejandro Imass) Date: Thu, 6 Mar 2014 11:22:05 -0500 Subject: [caracas-pm] Evaluar null en JSON In-Reply-To: References: Message-ID: 2014-03-06 10:47 GMT-05:00 Alberto Mijares : > Hola lista: > > Me est? ocurriendo algo muy extra?o y por eso consulto con ustedes. > > Tengo un script que consulta un webservice. Este devuelve un paquete > JSON. Aunque es un error que debe solucionar el desarrollador del > webservice, a veces me est? devolviendo valores null. Mientras eso se > soluciona de aquel lado, yo necesito manejar la excepci?n. Entonces > tengo, despu?s de inicializar mi objeto JSON y todo eso: > > for (@{$json->{lista}}) { > > my $valor; > > defined($_->{valor}) ? $valor = $_->{valor} : $valor = 'INDEFINIDO'; > > } > > Pero ocurre que siempre $valor = 'INDEFINIDO', y no siempre el valor > en el JSON es null. Se supone que un valor null en JSON se transforma > en undef, ?no es as?? > Asumo que es JSON > 2.x pq versiones previas tienen algunos problemitas. perldoc JSON busca MAPPING y lo que indicas es correcto, no obstante: Hay serializadores JSON que no usan false,true,null correctamente (ver http://www.json.org), o bien el programador del otro lado no sabe la diferencia entre un empty string, null y "null", o referencias vac?as tales como [] y {}. Para poder ayudarte mejor debes colocar un ejemplo del JSON que estas recibiendo. Null en JSON es el literal null sin comillas de esta forma: "key": null nota que no tiene comillas, y es diferente a "key":"null" y diferente a "key":, y es diferente a "key": { }, y es diferente si el "key" no existe. Es posible que estes recibiendo un { } por lo que quiz?s siempre est? defined. Si no quieres tomar riesgos y no hay un contrato claro con el otro lado, lo mejor es validar de izq a derecha TODO lo que puedas y aprovechar el short-circuit del operador && (i.e. que no sigue evaluando hacia la derecha una vez que alguno sea falso): my $scalar = defined $_->{valor} && ref $_->{valor} eq 'SCALAR' && $_->{valor} ne '' ? foo : bar; YAML/JSON son schema-less by design pero hay algunas iniciativas para crear esquemas y poder validar estructuras JSON/YAML antes de parsearlas y muchos argumentan que pierde el chiste de usar YAML in the first place. Por eso es importante que exista un buen contrato (o te resguardes bien) si vas a intercambiar informaci?n en JSON con otra gente en otras plataformas. Saludos, Alejandro From amijaresp at gmail.com Thu Mar 6 14:24:41 2014 From: amijaresp at gmail.com (Alberto Mijares) Date: Thu, 6 Mar 2014 17:54:41 -0430 Subject: [caracas-pm] Evaluar null en JSON In-Reply-To: References: Message-ID: > > Asumo que es JSON > 2.x pq versiones previas tienen algunos problemitas. > > perldoc JSON busca MAPPING y lo que indicas es correcto, no obstante: > > Hay serializadores JSON que no usan false,true,null correctamente (ver > http://www.json.org), o bien el programador del otro lado no sabe la > diferencia entre un empty string, null y "null", o referencias vac?as > tales como [] y {}. Para poder ayudarte mejor debes colocar un ejemplo > del JSON que estas recibiendo. Null en JSON es el literal null sin > comillas de esta forma: "key": null nota que no tiene comillas, y es > diferente a "key":"null" y diferente a "key":, y es diferente a > "key": { }, y es diferente si el "key" no existe. > > Es posible que estes recibiendo un { } por lo que quiz?s siempre est? > defined. Si no quieres tomar riesgos y no hay un contrato claro con el > otro lado, lo mejor es validar de izq a derecha TODO lo que puedas y > aprovechar el short-circuit del operador && (i.e. que no sigue > evaluando hacia la derecha una vez que alguno sea falso): > > my $scalar = defined $_->{valor} && ref $_->{valor} eq 'SCALAR' && > $_->{valor} ne '' ? foo : bar; > > YAML/JSON son schema-less by design pero hay algunas iniciativas para > crear esquemas y poder validar estructuras JSON/YAML antes de > parsearlas y muchos argumentan que pierde el chiste de usar YAML in > the first place. > > Por eso es importante que exista un buen contrato (o te resguardes > bien) si vas a intercambiar informaci?n en JSON con otra gente en > otras plataformas. Gracias por tu respuesta, Alejandro. Para estar seguro, lo que hice fue un print del objeto con Dumper $json; Efectivamente, el JSON viene bien y en Perl veo elementos como 'valor' => undef lo que quiere decir que no hay problemas con lo que estoy recibiendo. Lo que hice fue otras pruebitas con unos oneliners y encontr? algo interesante. Tal vez me ayudes a descifrarlo: $ perl -E '$h=[{a=>1,b=>undef}]; for (@{$h}) { defined($_->{b}) ? say "si" : say "no";};' y obtengo un "no", como es de esperar. Con $ perl -E '$h=[{a=>1,b=>undef}]; for (@{$h}) { defined($_->{b}) ? say "si" : say "no";};' obtengo un "si". Pero para reproducir exactamente mi pedazo de c?digo lo ampli? un poco $ perl -E '$h=[{a=>1,b=>undef},{a=>1,b=>2}]; for (@{$h}) { defined($_->{b}) ? $r=$_->{b} : $r=3; say $r;};' Yo hubiese esperado obtener 3 2 Pero no. Obtuve 3 3 ?Qu? opinas? Saludos Alberto Mijares From fobispo at isc.org Thu Mar 6 21:00:52 2014 From: fobispo at isc.org (Francisco Obispo) Date: Thu, 6 Mar 2014 21:00:52 -0800 Subject: [caracas-pm] Evaluar null en JSON In-Reply-To: References: Message-ID: <3AFDDAD1-3393-4CCB-8A92-126150D1C62A@isc.org> On Mar 6, 2014, at 2:24 PM, Alberto Mijares wrote: > $ perl -E '$h=[{a=>1,b=>undef},{a=>1,b=>2}]; for (@{$h}) { > defined($_->{b}) ? $r=$_->{b} : $r=3; say $r;};' > > Yo hubiese esperado obtener > > 3 > 2 > > Pero no. Obtuve > > 3 > 3 > > ?Qu? opinas? El problema es el orden en que se eval?an las operaciones: $ perl -E '$h=[{a=>1,b=>undef},{a=>1,b=>2}]; for (@{$h}) { defined $_->{b} ? ($r=$_->{b}) : ($r=3); say $r;};' 3 2 Yo usar?a // : Perl?s "//" operator is related to its C?style or. In fact, it?s exactly the same as "||", except that it tests the left hand side?s definedness instead of its truth. Thus, "$a // $b" is similar to "defined($a) || $b" (except that it returns the value of $a rather than the value of "defined($a)") and is exactly equivalent to "defined($a) ? $a : $b". This is very useful for providing default values for variables. If you actually want to test if at least one of $a and $b is defined, use "defined($a // $b)?. $ perl -E '$h=[{a=>1,b=>undef},{a=>1,b=>2}]; for (@{$h}) { say $_->{b} // 3 };' 3 2 From amijaresp at gmail.com Thu Mar 6 21:11:40 2014 From: amijaresp at gmail.com (Alberto Mijares) Date: Fri, 7 Mar 2014 00:41:40 -0430 Subject: [caracas-pm] Evaluar null en JSON In-Reply-To: <3AFDDAD1-3393-4CCB-8A92-126150D1C62A@isc.org> References: <3AFDDAD1-3393-4CCB-8A92-126150D1C62A@isc.org> Message-ID: On Fri, Mar 7, 2014 at 12:30 AM, Francisco Obispo wrote: > > On Mar 6, 2014, at 2:24 PM, Alberto Mijares wrote: > >> $ perl -E '$h=[{a=>1,b=>undef},{a=>1,b=>2}]; for (@{$h}) { >> defined($_->{b}) ? $r=$_->{b} : $r=3; say $r;};' >> >> Yo hubiese esperado obtener >> >> 3 >> 2 >> >> Pero no. Obtuve >> >> 3 >> 3 >> >> ?Qu? opinas? > > > > El problema es el orden en que se eval?an las operaciones: > > > $ perl -E '$h=[{a=>1,b=>undef},{a=>1,b=>2}]; for (@{$h}) { > defined $_->{b} ? ($r=$_->{b}) : ($r=3); say $r;};' > 3 > 2 > > > > Yo usar?a // : > > Perl?s "//" operator is > related to its C?style or. In fact, it?s exactly the same as "||", > except that it tests the left hand side?s definedness instead of its > truth. Thus, "$a // $b" is similar to "defined($a) || $b" (except that > it returns the value of $a rather than the value of "defined($a)") and > is exactly equivalent to "defined($a) ? $a : $b". This is very useful > for providing default values for variables. If you actually want to > test if at least one of $a and $b is defined, use "defined($a // $b)?. > > > > $ perl -E '$h=[{a=>1,b=>undef},{a=>1,b=>2}]; for (@{$h}) { > say $_->{b} // 3 };' > 3 > 2 > Francisco, muchas gracias. Que casualidad que justo en este momento estaba leyendo acerca de ese operador en perlop. No lo hab?a usado nunca y me dispon?a a ver c?mo funciona. Veo que mi problema era de precedencia. Lo llegu? a pensar pero nunca lo prob?. Doble aprendizaje el d?a de hoy ;-) Saludos Alberto Mijares