Crystal: JSON::Any#each should give string keys

Created on 13 Jan 2017  路  15Comments  路  Source: crystal-lang/crystal

json keys are required to be strings; if my underlying value is a hash, JSON::Any#each should give keys of type String, not of type JSON::Any. Any is a convenience wrapper, so let's make it more convenient.

Most helpful comment

@luislavena The idea would be to use casting, since JSON is highly dynamic (if you don't want to do that, use JSON.mapping). For example:

json = JSON.parse(string).as(Array) # expect an array as result
json.each do |value|
  value = value.as(Hash) # expect each item to be a Hash
  value["id"].as(Int) # expect id to be an int
  # and so on...
end

In fact this is what we had before JSON::Any, but I somehow thought it was going to be more intuitive to use...

The main issue is that everyone seems to want to use it like in Ruby, but that's impossible in a statically typed language. So it's probably better to face reality and force programmers to cast to the types they want.

All 15 comments

You can use JSON::Any#as_hash and Hash#each.

the problem with those is that you're then dealing with values of JSON::Type instead of JSON::Any; i want to stay with Any values and not worry about casting

@aeosynth I introduced JSON::Any#to_h and JSON::Any#to_a, which keeps values as JSON::Any, in #3883 just now. Thought?

i mean, this issue is about wanting to do less casting, so introducing new casts doesn't really help. also i think you implemented #3158.

How do you think this patch?

When apply this patch, you can write such a code:

require "json"

json = JSON.parse %({"hello": ["foo", "bar"], "world": 42})
json.each do |value, key|
  p value
  p typeof(value) # => JSON::Any
  p key
  p typeof(key)   # => String
end

But I don't think it is good idea.

Note: We cannot use key typed String without changing block arguments order because Crystal's block cannot be overloading.

The comment above is why keys can't just be strings. I'm closing this. @aeosynth Please provide your use case, without a use case we have no reasons to change JSON::Any

ok, thanks for explaining.

@asterite But I think JSON::Any#each definition is not so good because it is incompatible with Hash#each in spite of iterating over a Hash, in other words it is not useful against Hash. I think we should decide remove each method or it is specialized for Array.

I'd actually like to remove JSON::Any (and YAML::Any) from the standard library, I think it was a mistake.

@asterite are the constant issues with it's usage that are making you consider that scenario?

@luislavena Yes

@asterite understood. If that is the case, then the pull parser documentation and examples might need a bit of improvement in order to make it more easy to people use those instead of Any alternative.

Also how to combine the pull parser and the #mapping in order to return structured data from the JSON/YAML being parsed.

@luislavena The idea would be to use casting, since JSON is highly dynamic (if you don't want to do that, use JSON.mapping). For example:

json = JSON.parse(string).as(Array) # expect an array as result
json.each do |value|
  value = value.as(Hash) # expect each item to be a Hash
  value["id"].as(Int) # expect id to be an int
  # and so on...
end

In fact this is what we had before JSON::Any, but I somehow thought it was going to be more intuitive to use...

The main issue is that everyone seems to want to use it like in Ruby, but that's impossible in a statically typed language. So it's probably better to face reality and force programmers to cast to the types they want.

@asterite However for people who do know what the limitations of JSON::Any are, it's a useful tool for getting a quick PoC done before moving to JSON.mapping/JSON::PullParser. I guess the question is should crystal optimise for newcomers even at the (admittedly minor) detriment of productivity for people who know the langauge well? I would say not.

https://github.com/SwiftyJSON/SwiftyJSON
The SwiftyJSON project could be a way of doing JSON manipulations. @RX14

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stugol picture stugol  路  70Comments

xtagon picture xtagon  路  132Comments

ezrast picture ezrast  路  84Comments

malte-v picture malte-v  路  77Comments

rdp picture rdp  路  112Comments