As a little side note, I’d welcome the addition of a --log-defines arg to the compiler (name just made up) that pretty-prints them out, without having to resort to the verbose ouput of -v.
Another macro-powered idea would be to have an init macro (--macro in compiler args) that does Compiler.getDefine to check for other defines and then Compiler.define to set the common flag.
class Defines {
public static macro function isDefined(define:String) {
var v = haxe.macro.Context.definedValue(define);
if (v == null || v == "0" || v == "false") {
return macro false;
}
else {
return macro true;
}
}
}
Then you can just use
if (Defines.isDefined("no_io")) {
}
else
{
}
Haxe doesn’t output a real if-statement, because it optimizes constants away. I mean it always skips complete expression like this if(false) trace("aa"); in your output \o/.
Sure, I should have mentioned my use case earlier.
The main reason is because frequently I want to override the define in the .hxml with a new value directly from the command line.
Like in haxe build.hxml -D logging=false where logging was enabled in the hxml.
But generally was investigating ways of having shared define logic in a centralized place, so that I could run it on arbitrary defines (say for example also check the upper-cased version of a define).
Running this with -D logging=false:
#if (!logging)
#else
trace("Logged!");
#end
will actually run the trace line, as logging is defined, and has a value of "false".
macro static function fix_defines(defines:Array<String>) {
for (define in defines) {
var v = Context.definedValue(define);
if (!(v == null || v == "0" || v == "false")) {
haxe.macro.Compiler.define("real_" + define, "1");
}
}
return null;
}
and in your hxml:
--macro Main.fix_defines(["no_io", "verbose"])
Then you can use real_no_io and real_verbose like normal defines.
You can also prepend a # in hxml to comment, instead of setting it to false. Saves a few keystrokes, saves you some complexity too. Dont make something that is simple, complex
@mark.knol: fair point, I’m currently doing exactly that!
But I’m recently deep in the debugging process of a project with quite a few defines. The project itself takes seconds to run to completion. And I’ve found that changing the defines manually in the hxml is tedious and error prone (it’s painfully common to find out that I’ve forgot to change one of them only after the fact, meaning that I was working with the wrong assumptions. Me: ).
Moreover, as I said, I’m interested in seeing if there’s a generic way to do this kind of things.
Experimenting a bit with @ibilon’s last suggestion (the one based on @nadako’s idea (can’t mention him as per forum rules… I know!?)), led me to an interesting discovery: you can kind of undefine a define by assigning it an empty string.
PS: By the way, I’m enjoying the discussion so far, thanks!
I’ve been experimenting with a mix of the suggestions here, a bit clunky but it works.
(Not sure I’ll use this in an actual project, as it’s probably too opaque from the user point of view, but it was fun exploring the possibilities)
One thing I cannot find a solution for, is how to avoid the duplication of asBool() and __asBool(). I’d like to have just one method, callable both from actual code (like from TestAll.hx) and from fixBoolDefines (so from an init macro). I’ve tried multiple combinations but haven’t been successful so far, any tips?