my version
headers = task["headers"]?
.try &.as_h?
.try &.to_h { |k, v| {k, v.as_s} }
|| {} of String => String
my version
headers = task["headers"]?
.try &.as_h?
.try &.to_h { |k, v| {k, v.as_s} }
|| {} of String => String
I’d recommend having a read of if-var control flow from the docs, but to solve this you’d likely want to handle the nilable case earlier:
headers = task["headers"]?.try(&.as_h) || {} of String => JSON::Any
headers = headers.transform_values &.as_s
EDIT: typing & method fixes
Do you have a way to avoid receiving it as a JSON::Any
to begin with?
struct Task
include JSON::Serializable
getter headers : Hash(String, String)
# ...
end
task = Task.from_json(json)
Then task.headers
will just be a Hash(String, String)
and you won’t have to perform the conversion after it’s been parsed.
I know this but I don’t really like using it.
Based on my experience in other languages, Any is usually lazy parsed, but I don’t know if Crystal is also …
I would be thoroughly interested in understanding this perspective. Any time I reach for JSON::Any
it makes me want to swap it out in favor of JSON::Serializable
objects.
That depends on how you define “lazily”. It’s lazy in that you can parse from an IO
so that you don’t need to hold the entire JSON-serialized representation in memory before starting parsing, but it’s not the form of laziness where, for example, it won’t start parsing until you retrieve an object’s key. What is the importance of laziness here?