Is it possible to define methods relative to a generic type? Or access the generic type outside of methods at all? This:
module Moo(T)
{% if T < Number %}
def method(param1=true)
end
{% else %}
def method(param1=false)
end
{% end %}
end
yields this:
3 | {% if T < Number %}
^
Error: undefined constant T
But if I put that same statement within the method, it compiles fine.
Any ideas on how to vary a parameter value based on a generic type? For now I’m going to just use an Enum and have it default to 'default" and override it within the method if it’s “default” 
It doesn’t work like that because macros at the “top level” are expanded as soon as you reach them.
What you want is possible:
module Moo(T)
def method
method({{ T < Number }})
end
def method(param1)
end
end
1 Like
Nice! So I can set a default based on type.
I’m trying to satisfy https://github.com/crystal-lang/crystal/issues/6057 and was hoping to set
def sort(stable = false) : Array(T)
with the “stable” set to false for Number types and true for Objects (since stable doesn’t matter for Numbers). It appears that I won’t be able to do that in the type signature…
Anybody have any ideas on how to accomplish this? Suggestions? Enum? Thanks for any help.
Update: It appears I can use something like a param whose default value is a method call to accomplish it, thanks for the hints:
class Moo(T)
def get_type()
{{ T < Number }}
end
def method(param1 = get_type())
puts param1
end
end
Moo(Int32).new.method # => true
Moo(String).new.method # => false
You could also avoid the method and drop the macro into the argument list:
class Moo(T)
def method(param1 = {{ T < Number }})
puts param1
end
end
puts Moo(Int32).new.method # => true
puts Moo(String).new.method # => false
6 Likes