Cyan Ogilvie
Ruby Lane, Inc.
cyan@rubylane.com
{ "foo": "is this a dict?", "bar": null } { "foo": ["is", "this", "a", "dict?"], "bar": "" } { "foo": { "is": "this", "a": "dict?" }, "bar": "null" } |
➜ | foo {is this a dict?} bar {} |
or | ||
foo {is this a dict?} bar null |
{ "pin": { "location": { "lat": 40.12, "lon": -71.34 } } }
When generating JSON from Tcl the missing type info must be supplied
HUDDLE {D {pin {D {location {D {lat {s $lat} lon {s $lon}}}}}}}
map_open string pin map_open string location map_open string lat number $lat string lat number $lon map_close map_close map_close
{ "query": { "function_score": { "query": { "bool": { "must": [ { "function_score": { "query": { "function_score": { "functions": [ { "random_score": { "seed": 33485047948 } } ], "boost_mode": "replace" } }, "functions": [ { "script_score": { "lang": "expression", "params": { "logfactor": 1 }, "script": "1 + (sqrt(-1.57079632679 * ln(pow(1-(2*(_score*0.99 *0.5+0.5)-1), 2))) * ln(1+(1+doc['clickcomp_raw'].value)*min(1.1,doc['crf'].value)*logfactor)) * 1.0" } } ], "score_mode": "first", "boost_mode": "replace" } } ], "should": [], "must_not": [] } }, "filter": { "bool": { "must": [ { "term": { "shoptype": "rubylane" } }, { "terms": { "itemstatus": [ "retail", "sale", "reduced", "sold", "hold", "auction" ] } }, { "term": { "itemdisplayarea": "shop" } }, { "term": { "shopstatus": "active" } }, { "or": [ { "term": { "aip": true } }, { "term": { "aip_grandfathered": true } } ] } ], "should": [], "must_not": [ { "terms": { "shopnickname": [ "test", "karen", "jennifer", "rlshop", "dontletthishappen", "sampleshop", "rlwhatsthis", "rlwhatwasthis", "rubylane-sold", "rubylux-sold", "rubyplaza-sold", "rlreproshop", "rlgiftcardshop" ] } }, { "term": { "itemnrpics": 0 } } ] } }, "functions": [ { "filter": { "term": { "aip": true } }, "weight": 1.2 }, { "exp": { "starttime": { "origin": "now+1w/d", "scale": "1000d" } } }, { "filter": { "terms": { "lane": [ "jewelry", "rxjewelry" ] } }, "weight": 0.9 } ] } }, "post_filter": { "bool": { "must": [], "should": [], "must_not": [] } }, "sort": [ "itemstatus_sort", "_score" ], "fields": [ "_source" ], "size": 30, "from": 0, "aggregations": { "added_since": { "range": { "field": "starttime", "keyed": true, "ranges": [ { "key": "Today", "from": "now-24h/h" }, { "key": "This Week", "from": "now-168h/h" } ] } }, "price": { "range": { "field": "priceusd", "keyed": true, "ranges": [ { "key": "Under $25", "to": 25 }, { "key": "$25 - 49", "from": 25, "to": 50 }, { "key": "$50 - 99", "from": 50, "to": 100 }, { "key": "$100 - 199", "from": 100, "to": 200 }, { "key": "$200 - 499", "from": 200, "to": 500 }, { "key": "$500 - 999", "from": 500, "to": 1000 }, { "key": "$1,000 - 4,999", "from": 1000, "to": 5000 }, { "key": "Over $5,000", "from": 5000 } ] } }, "layaway_available": { "terms": { "field": "layaway", "size": 0 } }, "itemstatus": { "terms": { "field": "itemstatus", "size": 0 } }, "by_lane": { "terms": { "field": "lane", "size": 0 } } } }
[json] | is to |
{ "pin": { "location": { "lat": 40.12, "lon": -71.34 } } } |
... as ... | ||
[dict] | is to |
pin { location { lat 40.12 lon -71.34 } } |
{ "pin": { "location": { "lat": 40.12, "lon": -71.34 } } } rl_json uses templates to supply the missing type information: set lat 40.12 set lon -71.34 json template { { "pin": { "location": { "lat": "~N:lat", "lon": "~N:lon" } } } } |
Template type prefixes:
|
set someval 0xFF set res [json template { { "foo": "~S:someval", "bar": "~N:someval", "baz": [ "~B:someval", "~S:otherval", "~L:~S:someval" ] } }] json set res baz end+1 $res json set res new {"entry"} json unset res baz end baz end-1 puts [json pretty $res] puts "baz: [json get $res baz 0]" puts "is a [json get $res baz 0 ?type]" |
➜ |
{ "foo": "0xFF", "bar": 255, "baz": [ true, null, "~S:someval", { "foo": "0xFF", "bar": 255, "baz": [ true, "~S:someval" ] } ], "new": "entry" } baz: 1 is a boolean |
Sometimes types can be useful
set json { { "foo": "bar", "baz": ["str", 123, 123.4, true, false, null, {"inner": "target"}] } } json get $json baz end inner dict get [lindex [dict get [json::json2dict $json] baz] end] inner
Available on the Ruby Lane github page: https://www.github.com/RubyLane
Licensed under the same terms as the Tcl core