Optional shard required or not

How can I check if an optional shard has been required or not ?
for example:

{% if ?shard required? %}
{% else %}
Different code...
{% end %}

There isn’t really a direct way to do this. Best work around would be to like check if a type from that shard exists. E.g.

{% if @top_level.has_type?("MyShard") %}
  # `MyShard` is required
{% end %}

The catch is you’d have to pick a type that is for sure only going to exist in the shard, and not re-opened in your lib as it would otherwise trick the logic into thinking that shard was actually installed.

Another option could be using a compile time flag. This would deff be more specific and probably less brittle, but also a bit more verbose. E.g. crystal build -Dwith_my_shard src/app.cr, then check with {% if flag? :with_my_shard %}. An ENV var could also work but like {% if env("WITH_MY_SHARD") == "1" %} or something along those lines.

Related: Check whether a required file / shard exists on Compilation time?

I don’t think you can do this at compiletime. Your program either compiles or it doesn’t. But I suppose it’s possible via runtime, you would just include the code normally, but conditionalize when it’s called?

There is a bit more nuance than that. However, it can’t be guaranteed because macros are evaluated in source order. If the expected require comes after the check, it’ll do the wrong thing.

Thanks @Blacksmoke16, your first workaround works fine (with has_constant?, however :wink:)
I simply used the Module name (which is very specific) defined in the optional shard and did not encounter any problem.
As I use this optional shard in my own shard, I find this solution preferable to the second one, as it keeps the optional nature of the optional shard, without the need to modify the compilation command line.

:+1:. Yea that’s fair. The main benefit of the flag is it’ll more robust and not dependent on the order in which things are required. E.g. if you do your check before the shard is actually required, it won’t actually work. Maybe could wrap it in a macro finished but :person_shrugging:.