func() { local varname="CLASS_${DEFCLASS}_FUNCTIONS" eval "$varname=\"\${$varname}$1 \"" }
var() { local varname="CLASS_${DEFCLASS}_VARS" eval $varname="\"\${$varname}$1 \"" }
loadvar() { eval "varlist=\"\$CLASS_${CLASS}_VARS\"" for var in $varlist; do eval "$var=\"\$INSTANCE_${THIS}_$var\"" done }
loadfunc() { eval "funclist=\"\$CLASS_${CLASS}_FUNCTIONS\"" for func in $funclist; do eval "${func}() { ${CLASS}::${func} \"\$@\"; return \$?; }" done }
savevar() { eval "varlist=\"\$CLASS_${CLASS}_VARS\"" for var in $varlist; do eval "INSTANCE_${THIS}_$var=\"\$$var\"" done }
typeof() { eval echo \$TYPEOF_$1 }
new() { local class="$1" local cvar="$2" shift shift local id=$(uuidgen | tr A-F a-f | sed -e "s/-//g") eval TYPEOF_${id}=$class eval $cvar=$id local funclist eval "funclist=\"\$CLASS_${class}_FUNCTIONS\"" for func in $funclist; do eval "${cvar}.${func}() { local t=\$THIS; THIS=$id; local c=\$CLASS; CLASS=$class; loadvar; loadfunc; ${class}::${func} \"\$@\"; rt=\$?; savevar; CLASS=\$c; THIS=\$t; return $rt; }" done eval "${cvar}.${class} \"\$@\" || true" }
#--------------------------------------------------- # Example code #---------------------------------------------------
# class definition class Storpel func Storpel func setName func setQuality func print var name var quality
# class implementation Storpel::Storpel() { setName "$1" setQuality "$2" if [ -z "$name" ]; then setName "Generic"; fi if [ -z "$quality" ]; then setQuality "Normal"; fi }
C语言的多行宏定义, 很多都使用 do {} while(0) 的形式. 比如 PHP 源码中就有很多这样的定义. 我们知道 do {} while 是循环结构, 在C语言中, 这种形式, 会先执行 do {} 中的语句, 再执行 while 中的判断条件. 也就是无论 while 中的条件是什么, do {} 中语句至少会执行一次. 而且 while(0), 所以 do {} 就只执行一次.
这是为什么呢?
我们来看一个例子:
1
#define TEST(a, b) a++; b++;
这是个宏声明.
如果这个宏使用以下场景中
1 2 3 4
if (cond) TEST(a, b); else ...
这种情况下, 编译器会报错. 因为宏替换后, if () 后只包含 a++; 而 b_++; 会被编译器认为是 if 之外的语句.