還記得以前那個用算素數的Regex嗎?編程這個世界太有趣了,總是能看到一些即別出心裁的東西。你有沒有想過在寫Shell指令碼的時候可以把你的變數和函數放到一個類中?不要以為這不可能,這不,我在網上又看到了一個把Shell指令碼整成物件導向的東西。Shell本來是不支援的,需要自己做點東西,能搞出這個事事的人真的是hacker啊。
當然,這裡並不是真正的物件導向,因為其只是封裝罷了,還沒有支援繼承和多態。最變態的是他居然還支援typeid,靠!
下面讓我們看看他是怎麼來做的。下面的指令碼可能會有點費解。本想解釋一下,後來想想,還是大家自己專研一下吧,其實看懂也不難,給大家提幾個點吧。
- 我們可以看到,下面的這個指令碼定義了class, func, var, new 等函數,其實這些就是所謂的關鍵字。
- class是一個函數,主要是記錄類名。
- func和var實際上是把成員函數名和成員變數記成有相同首碼的各種變數。
- new方法主要是記錄執行個體。大家重點看看new函數裡的那個for迴圈,最核心的就在那裡了。
指令碼如下所示:
# -------------------------------------------------------------------# OO support functions# Kludged by Pim van Riezen <pi@madscience.nl># -------------------------------------------------------------------DEFCLASS=""CLASS=""THIS=0 class() { DEFCLASS="$1" eval CLASS_${DEFCLASS}_VARS="" eval CLASS_${DEFCLASS}_FUNCTIONS=""} static() { return 0} 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 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"}