On Feb 7, 2013, at 3:00 AM, rosenfeld (Rodrigo Rosenfeld Rosas) wrote:

>=20
> Issue #7792 has been updated by rosenfeld (Rodrigo Rosenfeld Rosas).
>=20
>=20
> rosenfeld (Rodrigo Rosenfeld Rosas) wrote:
>=20
>> cache =3D Redis.new
>> users =3D cache['users'] || begin
>>    db =3D Sequel.connect('postgres://user:password@localhost/mydb')
>>    cache['users'] =3D db[:users].select(:id, :name).map{|r| id: =
r[:id],=20
>> name: r[:name]} # or just select(:id, :name).all
>=20
> Sorry, I forgot the JSON conversion in the example above:
>=20
>  cache =3D Redis.new
>  db =3D Sequel.connect('postgres://user:password@localhost/mydb')
>  users =3D if cached =3D cache['users']
>    JSON.parse cached
>  else
>    db[:users].select(:id, :name).all.tap{|u| cache['users'] =3D =
JSON.unparse u}
>  end

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.

> 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)

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.

Dave