Take a look at this example: https://play.crystal-lang.org/#/r/4hqb
Here's the code (don't know how long that link is good for...)
require "json"
class House
JSON.mapping(address: String)
getter first_part
def initialize
@first_part = address.split(" ")[0]
end
end
house = House.from_json(%({"address": "Crystal Road 1234"))
puts house.first_part
It's the basics of the JSON.mapping example in the docs. Except I added an initialize
which does something with the JSON data (address).
The trouble is we get this error:
Error in line 8: this 'initialize' doesn't explicitly initialize instance variable '@address' of House, rendering it nilable
Questions:
So far this is what I've come up with. I don't love it, but it achieves what I want. The two key things are:
Both are documented here: https://crystal-lang.org/docs/syntax_and_semantics/methods_and_instance_variables.html
class House
@first_part = ""
JSON.mapping(
address: {type: String, nilable: false}
)
getter first_part
def initialize(pull : JSON::PullParser)
previous_def
@first_part = address.split(" ")[0]
end
end
house = House.from_json(%({"address": "Crystal Road 1234"}))
puts house.first_part
Note: I say I don't love it because I feel like defining @first_part the way I do below guarantees it'll be a string and the previous_def
call should just paste the code into the initializer defined by the JSON.mapping macro. Instead, because of the two definitions, we get an error that @first_part was not properly initialized in all of the initialize methods.