On Feb 7, 2013, at 10:23 AM, rosenfeld (Rodrigo Rosenfeld Rosas) wrote:

>=20
> Issue #7792 has been updated by rosenfeld (Rodrigo Rosenfeld Rosas).
>=20
>=20
> david_macmahon (David MacMahon) wrote:
>> I still think the fundamental issue is that Sequel is returning =
something that contains symbols, but JSON.parse(JSON.unparse(x)) will =
never return anything containing a symbol even if x does.  Because of =
this the "users" variable is assigned something that contains symbols in =
one case and something that contains no symbols in all other cases.  =
IMHO, the example shows not a deficiency in the Ruby language itself but =
rather a (subtle, easy to fall victim to) coding pitfall of not properly =
managing/reconciling the incompatible return types from the two =
libraries.
>=20
> But don't you agree that we wouldn't have this kind of problem if =
Symbols behave just like Strings? Or if Symbols didn't exist at all? Or =
even if hashes always behaved as HWIA?

Yes, I agree that we wouldn't have this kind of problem if any of those =
alternatives existed.  I'm just not (yet) convinced that any of those =
alternatives are desirable just to avoid this kind of problem.  I do =
somewhat like the idea of having Hash behave as HWIA.  I think the =
number of real world uses of something like:

{:a =3D> 0, 'a' =3D> 1}

is likely to be very small.

>>> I know the code above could be simplified, but I'm avoid the parse =
-> unparse operation when it is not required (although it would make the =
code always work in this case):
>>>=20
>>> users =3D JSON.parse (cache['users'] ||=3D JSON.unparse =
db[:users].select(:id, :name).all)
>>=20
>> This seems an excellent solution IMHO as it clearly results in =
"users" being assigned the return value of JSON.parse every time and =
only results in one extra JSON.parse call only on the first time =
through.  That seems a pretty small price to pay for reconciling the two =
libraries' incompatible return return types.
>=20
> An extra parse operation on a big list could easily add 100ms to the =
request timing.

So use explicit initialization instead of lazy initialization.

> Also, it doesn't happen only the first time but on each request.

In the original example, JSON.parse was used on every call except the =
first one.  The modified example uses JSON.parse on every call including =
the first one.  That's why I said the modified example has only one =
extra JSON.parse call (i.e. the one extra one on the first call).  If =
that's too much overhead, either don't use lazy initialization or =
explicitly invoke the method once at startup to force lazy =
initialization so it doesn't impact the (un?)lucky first user.

Dave