{"action":"created","issue":{"url":"https://api.github.com/repos/crystal-lang/crystal/issues/3158","repository_url":"https://api.github.com/repos/crystal-lang/crystal","labels_url":"https://api.github.com/repos/crystal-lang/crystal/issues/3158/labels{/name}","comments_url":"https://api.github.com/repos/crystal-lang/crystal/issues/3158/comments","events_url":"https://api.github.com/repos/crystal-lang/crystal/issues/3158/events","html_url":"https://github.com/crystal-lang/crystal/issues/3158","id":171223495,"number":3158,"title":"[Proposal] JSON::Any all the way down","user":{"login":"feifanzhou","id":3407996,"avatar_url":"https://avatars.githubusercontent.com/u/3407996?v=3","gravatar_id":"","url":"https://api.github.com/users/feifanzhou","html_url":"https://github.com/feifanzhou","followers_url":"https://api.github.com/users/feifanzhou/followers","following_url":"https://api.github.com/users/feifanzhou/following{/other_user}","gists_url":"https://api.github.com/users/feifanzhou/gists{/gist_id}","starred_url":"https://api.github.com/users/feifanzhou/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/feifanzhou/subscriptions","organizations_url":"https://api.github.com/users/feifanzhou/orgs","repos_url":"https://api.github.com/users/feifanzhou/repos","events_url":"https://api.github.com/users/feifanzhou/events{/privacy}","received_events_url":"https://api.github.com/users/feifanzhou/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/crystal-lang/crystal/labels/draft","name":"draft","color":"00B8B8"},{"url":"https://api.github.com/repos/crystal-lang/crystal/labels/RFC","name":"RFC","color":"009800"},{"url":"https://api.github.com/repos/crystal-lang/crystal/labels/standard%20library","name":"standard library","color":"fad8c7"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":14,"created_at":"2016-08-15T17:52:15Z","updated_at":"2016-08-16T15:13:42Z","closed_at":null,"body":"Currently, trying to work with a JSON collection wrapped as a `JSON::Any` will give me the raw `JSON::Type` one level down:\r\n\r\n```cr\r\nJSON.parse(\"[{\\\"key\\\": \\\"value\\\"}]\").as_a\r\n```\r\n\r\nThis returns `Array(JSON::Type)`. If I wanted to work with that inner hash, I'd have to manually wrap it into another `JSON::Any`:\r\n\r\n```cr\r\nJSON.parse(\"[{\\\"key\\\": \\\"value\\\"}]\").as_a.map{ |h| JSON::Any.new(h) }\r\n```\r\n\r\nThis will give me a `Hash(String, JSON::Type)`. Repeat for working with values in the hash. \r\n\r\nInstead, can we have `as_a` return `Array(JSON::Any)` and `as_h` return `Hash(String, JSON::Any)` so they behave more intuitively? The JSON types will \"disappear\" a bit more, leading to more intuitive behavior that more closely matches `JSON.parse` behavior in Ruby.\r\n\r\nIf there actually _is_ an easy way to chain or automatically convert `JSON::Type` that I've missed, that's awesome! Maybe we could make it more obvious in the docs :)"},"comment":{"url":"https://api.github.com/repos/crystal-lang/crystal/issues/comments/240133711","html_url":"https://github.com/crystal-lang/crystal/issues/3158#issuecomment-240133711","issue_url":"https://api.github.com/repos/crystal-lang/crystal/issues/3158","id":240133711,"user":{"login":"RX14","id":2788811,"avatar_url":"https://avatars.githubusercontent.com/u/2788811?v=3","gravatar_id":"","url":"https://api.github.com/users/RX14","html_url":"https://github.com/RX14","followers_url":"https://api.github.com/users/RX14/followers","following_url":"https://api.github.com/users/RX14/following{/other_user}","gists_url":"https://api.github.com/users/RX14/gists{/gist_id}","starred_url":"https://api.github.com/users/RX14/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RX14/subscriptions","organizations_url":"https://api.github.com/users/RX14/orgs","repos_url":"https://api.github.com/users/RX14/repos","events_url":"https://api.github.com/users/RX14/events{/privacy}","received_events_url":"https://api.github.com/users/RX14/received_events","type":"User","site_admin":false},"created_at":"2016-08-16T15:13:42Z","updated_at":"2016-08-16T15:13:42Z","body":"@ozra `JSON::Any` is effectively a wrapper around the casts which lets you perform basic operations on the value by asserting if the operator you are using works on the contained type. Using `.as` and using `JSON::Any` have the same levels of safety because they both assert the same things, except one is implicit and easier to use and read."}}
{"actor":{"display_login":"RX14"}}