Lately, I’ve spent a lot of time “cleaning” the .gmic
files located in gmic-community/include
(i.e. G’MIC commands and filters written by others).
I’ve seen some rather strange stuffs, so I think it could be interesting to summarize some of the bad practices I’ve encountered, and explain how to make the code cleaner.
If you are not a G’MIC script writer, it probably won’t be of any interest to you
Let’s start!
Indent your code:
No particular example here, but of course, indenting code is a good practice to better understand the code, particularly when using nested conditions and loops.
Please don’t use the TAB
character, as this never renders the same on different text editors.
Testing a condition:
In G’MIC, the commands if
, elif
, while
and repeat
expect a math expression as an argument, and the argument will always be evaluated. Therefore, forcing the argument evaluation using braces {expression}
is not necessary (and slower).
So,
if $var1==$value1" && "($var2==$value2" || "$var2==$value3)
...
fi
will work OK. No need for
if {$var1==$value1" && "($var2==$value2" || "$var2==$value3)}`
or, even worse (as I’ve seen it from times to times) :
if {{{$var1==$value1}" && "{{$var2==$value2}" || "{$var2==$value3}}}
In the latter, the math expression evaluator is called 6 times instead of once!
(you have to remember that each call of the math evaluator mostly involves parsing an expression + compiling it into bytecode before evaluation…)
Testing a variable against multiple values:
The G’MIC language has no specific syntax for that case, as we have in C/C++ with:
switch(variable) { case value1: ... case value2: ... }
, so, basically we have two solutions for doing that:
- Using
if...elif...elif...fi
:
if $variable==0
# Do something
elif $variable==1
# Do something else
elif $variable==2
# Do something else
else
# Do something else, corresponds to the `default` case in C/C++.
fi
Please think about using elif
! I’ve seen quite bad things like:
if $variable==0
# Do something
else
if $variable==1
# Do something else
else
if $variable==2
# Do something else
else
# Default case.
fi
fi
fi
and this, sometimes without indentation! Definitely harder to read and understand.
- Anyway, use the construction above only when you need to do very different stuffs for each case. For instance, if you just need to set a different value for a variable (e.g. the name of a command to perform colorspace conversion), then
${arg\ ...}
is your friend, e.g.:
convert_colors_fwd=${arg\ 1+$1,rgb2hsi,rgb2hsl,rgb2hsv,rgb2lab}
convert_colors_bwd=${arg\ 1+$1,hsi2rgb,hsl2rgb,hsv2rgb,lab2rgb}
$convert_colors_fwd[-1]
# Do something...
$convert_colors_bwd[-1]
This will save you a lot of lines of code.
More to come