面向对象的Shell脚本

Shell本来是不支持面向对象,当然,这里并不是真正的面向对象,因为其只是封装罢了,还没有支持继承和多态。脚本如下所示:

#!/bin/bash
 
# -------------------------------------------------------------------
# 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"
}

 

代码阅读提示:

  1. 我们可以看到,下面的这个脚本定义了class,  func, var, new 等函数,其实这些就是所谓的关键字。
  2. class是一个函数,主要是记录类名。
  3. func和var实际上是把成员函数名和成员变量记成有相同前缀的各种变量。
  4. new方法主要是记录实例。大家重点看看new函数里的那个for循环,最核心的就在那里了。

下面是个使用例程:

# -------------------------------------------------------------------
# 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
}
 
Storpel::setName() { name="$1"; }
Storpel::setQuality() { quality="$1"; }
Storpel::print() { echo "$name ($quality)"; }
 
# usage
new Storpel one "Storpilator 1000" Medium
new Storpel two
new Storpel three
 
two.setName "Storpilator 2000"
two.setQuality "Strong"
 
one.print
two.print
three.print
 
echo ""
 
echo "one: $one ($(typeof $one))"
echo "two: $two ($(typeof $two))"
echo "three: $three ($(typeof $two))"
 

 

 
posted @ 2012-12-29 17:40  startcool  阅读(2298)  评论(0编辑  收藏  举报