I watched the shared libraries in D video earlier today and one of the things mentioned was using a library only if it is available, and it rekindled something I wanted to do a while ago and couldn't: expand a module if and only if some other module is available.

Well, I could do it, but it meant using -versions. I'd prefer it if it worked with just listing the module.

But I think I have a solution now:

template moduleIsAvailable(string name) {
        enum moduleIsAvailable =
                mixin("__traits(compiles, { import " ~ name ~ "; } )")
                ? true : false;
}

        pragma(msg, moduleIsAvailable!"test");
        pragma(msg, moduleIsAvailable!"not.existing");

It returned true and false, so cool. If a module is available though, this test actually imports it and if you don't add its object file, you'll get a linker error:

$ dmd test11
true
false
test11.o:(.data+0x50): undefined reference to `_D4test12__ModuleInfoZ'


But that might be ok, since if it is available, you'll probably be using it anyway - if not, why would you test? Though it would be cool if there was some kind of technique we could use such that it only pulls if the module is actually used elsewhere, like a low priority linker symbol or something. But I don't know about that.


Anyway, with this, you can wrap the usage of a module inside a static if(moduleIsAvailable) {} and offer some magical expansion of interoperability (though, granted, this kind of thing might be best put into a third module anyway), or a graceful degradation if you want a file to combine with a library and be standalone at the same time.


The -version method might be better anyway though, since it is more explicit.... so I'm on the fence as to if I should actually use this. What do you all think? Bad idea or worth doing to have one file be both standalone and interconnected at the same time?

Reply via email to