code:
macro foo(obj)
p {{ obj.type }}
end
record Book, name : String, price : Float32
book = Book.new("foo", 33)
foo book
output:
10 | foo book
^---
Error: undefined macro method 'Var#type'
code:
macro foo(obj)
p {{ obj.type }}
end
record Book, name : String, price : Float32
book = Book.new("foo", 33)
foo book
output:
10 | foo book
^---
Error: undefined macro method 'Var#type'
The macro only knows it was given a variable, there isn’t a way to figure out the type of it at compile time given book is a runtime thing. Going to have to provide it manually as a second argument, or try and figure something else out.
Crystal isn’t the static type? The type of var should be inferenced in compile-time
You can use a normal def with a free variable:
def foo(obj : T) forall T
{% p T %} # okay
p T # okay
end
Value type will cause copy , so macro must be used in some scenarios
Does it matter? Book is so small in this scenario that it shouldn’t.
Do you even need compile-time access to the variable’s type? Does book.class or typeof(book) not work for your use case?
for example:
def get_instance_pointer(t : T) : Pointer(T) forall T
{% begin %}
{% if T.struct? %}
pointerof(t)
{% elsif T.class? %}
t.as(Pointer(T))
{% else %}
raise "{{T}} is neither struct nor class"
{% end %}
{% end %}
end
Do you realize that pointerof(t) is only valid within the method to which t is an argument?
If you leak that pointer outside the method, it will be broken because t on the stack is out of scope.
yes, so my question is How to get type of var in macro ![]()
You still don’t need to get the type in this case, because only runtime checks are needed, not compile-time checks:
macro get_instance_pointer(t)
{% raise "`t` must be a Var, not #{t.class_name}" unless t.is_a?(Var) %}
{{ t }}.is_a?(Reference) ? {{ t }}.as(Pointer(T)) : pointerof({{ t }})
end
But note that t.as(Pointer(T)) is simply invalid as that effectively introduces an additional level of indirection. I am not sure what get_instance_pointer is supposed to achieve.
I just want to give an example to explain that if you can get variable types in the macro, you can do more ;-)
Thank you for your patience anyway