I’m trying to implement numbers and bytes fields -only objects encoding to compact binary format and at first stuck with @type.instance_vars not working before fields initialization (for what I thought it could be used):
module Encodable
macro included
def initialize(bytes : Bytes)
{% for v in @type.instance_vars %} # `TypeNode#instance_vars` cannot be called in the top-level scope: instance vars are not yet initialized
{% if v.id == UInt32.id %}
@{{v.name.id}} = 0_u32
{% elif v.id == Bytes.id %}
@{{v.name.id}} = Bytes.new 0
{% end %}
{% end %}
end
end
end
struct Example
include Encodable
getter i : UInt32
getter b : Bytes
def initialize(@i, @b)
end
end
puts Example.new Bytes.new 0
However, it is used in JSON::Serializable implementation, so I tried copying details like verbatim and new, although having no idea how it can help:
module Encodable
macro included
def self.new(bytes : Bytes)
new_from_bytes(pull)
end
private def self.new_from_bytes(bytes : Bytes)
instance = allocate
instance.initialize bytes
::GC.add_finalizer(instance) if instance.responds_to?(:finalize)
instance
end
def initialize(bytes : Bytes)
{% verbatim do %}
{% for v in @type.instance_vars %}
{% if v.id == UInt32.id %}
@{{v.name.id}} = 0_u32
{% elif v.id == Bytes.id %}
@{{v.name.id}} = Bytes.new 0
{% end %}
{% end %}
{% end %}
end
end
end
struct Example
include Encodable
getter i : UInt32
getter b : Bytes
def initialize(@i, @b)
end
end
puts Example.new Bytes.new 0
which leads to kinda expectable from verbatim usage Error: instance variable '@i' of Example was not initialized in this 'initialize', rendering it nilable. Certainly there is something I missing here, maybe someone can give a clue