i just finished testing mine, had a big delay when i discovered hashtable names and items can have * and ? in them, and had to build a regex which im crap at. Try this out, its docuemnted so shouldnt be to hard to understand.
Code:
;
; *****************************************************************
; *  Script to add commands to run when a hashtable item unsets.  *
; *****************************************************************
;
; Altered commands   /hadd -r N table item value $chr(N) command
;
;   In the altered -r command N represents the asc value of the delimiter character between "value" and "command" (ie token seperator)
;
;   The altered command must be incorperated into a standard /hadd command that well produce an unsetting item, example... 
;     /hadd -ru100 44 myTable myItem myValue , echo -s Hashtable myTable Item myItem set at $time just unset at $!time
;
;   If the /hadd command does not create a item that has an $hget(table,item).unset value the command well be ignored.
;
;
;
; Added commands     /hcmd -Ww[s|c|d] N table item command  : Used to show, change or delete commands.
;                    $hcmd(-Ww[s|c|d],N,table,item,command) : Used to show, change or delete commands.
;   Exact Match Usage...
;     Show             /hcmd -s table item
;     Change           /hcmd -c table item command
;     Delete           /hcmd -d table item
;
;   Wildmatch Usage...
;     Show Wildmatch Table         /hcmd -sW N table item
;     Show Wildmatch Item          /hcmd -sw N table item
;     Show Wildmatch Table & Item  /hcmd -sWw N table item
;       In wildcard matches N represents the Nth match, N = 0 returns the total number of matches.
; 
;   The following values are returned from this identifier
;     $1  =  hashtable name
;     $2  =  hashtable item
;     $3- =  command
;
;   Switches -s -c -d are mutually exclusive commands, in the event two or more are present -s superseeds -c which superseeds -d.
;
;
;
; Added events       on *:signal:hashtable.on.unset.command.stack:{ } A example event is at the bottom of this file.
;
;   This event triggers when a hashtable item is detected to have been unset, this normally is within .5 seconds but may be longer.
;
;   The following values are passed to this event
;     $1  =  Estermated tick count at unset time this well be lower than the current $tick but well not always match near the time of the unset
;     $2  =  Internal counter of number of incorrect estermations of the $1 value that were updated (if zero unset most likely within .5 seconds)
;     $3  =  cid of the script that produced (/hadd -r) or last updated (/hcmd -c) the command
;     $4  =  hashtable name
;     $5  =  item name
;     $6- =  command
;
;
;
; Monitored Commands  
;   /hfree well remove all unset event commands for table when table is destroyed
;   /hinc  well remove any unset event command for table item if item no longer has an $hget(table,item).unset value
;   /hdec  well remove any unset event command for table item if item no longer has an $hget(table,item).unset value
;   /hdel  well remove any unset event command for table item when table item is detroyed
;
alias hcmd {
  if (-* !iswm $1) {
    var %number = 1
    var %table.name = $Make.Regex.Ready($1)
    var %table.item = $Make.Regex.Ready($2)
    var %command = $3-
  }
  else {
    if (-*w* iswm $1) {
      var %number = $2
      var %table.name = $Make.Regex.Ready($3)
      var %table.item = $Make.Regex.Ready($4)
      var %command = $5-
      if (-*W* iswmcs $1) {
        %table.name =  $replace(%table.name,\*,.*,\?,.)
      }
      if (-*w* iswmcs $1) {
        %table.item =  $replace(%table.item,\*,.*,\?,.)
      }
    }
    else  {
      var %number = 1
      var %table.name = $Make.Regex.Ready($2)
      var %table.item = $Make.Regex.Ready($3)
      var %command = $4-
    }
  }
  if (-*s* iswm $1) || (-* !iswm $1) || ((-*c* !iswm $1) && (-*d* !iswm $1)) {
    var %line = $fline($hashtable.on.unset.command.stack,/^\d+\x9\d+\x9\d+\x9 $+ %table.name $+ \x9 $+ %table.item $+ \x9.*$/,%number,2)
    if (%line) && (%number != 0) {
      %line = $line($hashtable.on.unset.command.stack,%line)
      %line = $gettok(%line,4,9) $gettok(%line,5,9) $gettok(%line,6-,9)
    }
    if ($isid = $false) && (%line != $null) {
      echo -se /hcmd: $1-
      echo -se /hcmd: %line
    }
    return %line
  }
  elseif (-*c* iswm $1) && (%number != 0) {
    var %line = $fline($hashtable.on.unset.command.stack,/^\d+\x9\d+\x9\d+\x9 $+ %table.name $+ \x9 $+ %table.item $+ \x9.*$/,%number,2)
    rline $hashtable.on.unset.command.stack %line $puttok($gettok($line($hashtable.on.unset.command.stack,%line),1-5,9),$cid,3,9) $+ $chr(9) $+ %command
  }
  elseif (-*d* iswm $1) && (%number != 0) {
    var %line = $fline($hashtable.on.unset.command.stack,/^\d+\x9\d+\x9\d+\x9 $+ %table.name $+ \x9 $+ %table.item $+ \x9.*$/,%number,2)
    dline $hashtable.on.unset.command.stack %line
  }
}
;hmake * no alias needed
alias hfree {
  hfree $1-
  if (-* iswm $1) {
    var %table.name = $Make.Regex.Ready($2)
    if (-*w* iswm $1) {
      %table.name =  $replace(%table.name,\*,.*,\?,.)
    }
  }
  else {
    var %table.name = $Make.Regex.Ready($1)
  }
  filter -cxgww $hashtable.on.unset.command.stack $hashtable.on.unset.command.stack  /^\d+\x9\d+\x9\d+\x9 $+ %table.name $+ \x9.*$/
}
alias hadd {
  if (-*r* !iswm $1) {
    hadd $1-
  }
  else {
    if ($2 !isnum 1-255) {
      echo -se /hadd: /hadd -r option requires the following format /hadd -r N table item value $!chr(N) command.
      echo -se /hadd: N must be from 1 to 255 and selects the delimiter character that must appear between the hashtable value and unset event command.
      echo -se /hadd: It is preferable that the delimiter does not appear anywhere else on the line.
      halt
    }
    else {
      var %command = $gettok($5-,2-,$2)
      tokenize 32 $1 $3 $4 $gettok($5-,1,$2)
      hadd $1-
      hadd.hashtable.on.unset.command.stack $1 $2 $3 %command
    }
  }
}
alias hinc {
  hinc $1-
  if (-* iswm $1) tokenize 32 $2-
  update.hashtable.on.unset.command.stack $1-
}
alias hdec {
  hdec $1-
  if (-* iswm $1) tokenize 32 $2-
  update.hashtable.on.unset.command.stack $1-
}
alias hdel {
  hdel $1-
  hdel.hashtable.on.unset.command.stack $1-
}
alias -l update.hashtable.on.unset.command.stack {
  var %table.name = $Make.Regex.Ready($1)
  var %table.item = $Make.Regex.Ready($2)
  var %line.number = $fline($hashtable.on.unset.command.stack,/^\d+\x9\d+\x9\d+\x9 $+ %table.name $+ \x9 $+ %table.item $+ \x9.*$/,1,2)
  if (%line.number) {
    var %line = $line($hashtable.on.unset.command.stack,%line.number)
    hadd.hashtable.on.unset.command.stack -r $1 $2 $gettok(%line,6-,9)
  }
}
alias -l hadd.hashtable.on.unset.command.stack {
  hdel.hashtable.on.unset.command.stack $2 $3
  if (-*r* iswm $1) && ($hget($2,$3).item != 0) && ($hget($2,$3).unset > 0) {
    aline $hashtable.on.unset.command.stack [ $calc($ticks + $ifmatch * 1000) ] $+ $chr(9) $+ 0 $+ $chr(9) $+ $cid $+ $chr(9) $+ $2 $+ $chr(9) $+ $3 $+ $chr(9) $+ $4-
  }
}
alias -l hdel.hashtable.on.unset.command.stack {
  if (-* iswm $1) {
    var %table.name = $Make.Regex.Ready($2)
    var %table.item = $Make.Regex.Ready($3)
    if (-*w* iswm $1) {
      %table.item =  $replace(%table.item,\*,.*,\?,.)
    }
  }
  else {
    var %table.name = $Make.Regex.Ready($1)
    var %table.item = $Make.Regex.Ready($2)
  }
  filter -cxgww $hashtable.on.unset.command.stack $hashtable.on.unset.command.stack  /^\d+\x9\d+\x9\d+\x9 $+ %table.name $+ \x9 $+ %table.item $+ \x9.*$/
}
alias -l Make.Regex.Ready {
  var %text = $replace($1-,   \,\\,   $chr(32),\s,   $,\$,   $chr(40),\ $+ $chr(40),   $chr(41),\ $+ $chr(41),   *,\*,   +,\+,   .,\.,   ?,\?,   [,\[,   ],\],   ^,\^,   $chr(123),\ $+ $chr(123),   |,\|,   $chr(125),\ $+ $chr(125))
  var %text = $replace(%text, \s,$chr(32),   a,(a|A),b,(b|B),c,(c|C),d,(d|D),e,(e|E),f,(f|F),g,(g|G),h,(h|H),i,(i|I),j,(j|J),k,(k|K),l,(l|L),m,(m|M),n,(n|N),o,(o|O),p,(p|P),q,(q|Q),r,(r|R),s,(s|S),t,(t|T),u,(u|U),v,(v|V),w,(w|W),x,(x|X),y,(y|Y),z,(z|Z),   $chr(32),\s)
  return ( $+ %text $+ )
}
alias hashtable.on.unset.command.stack {
  if (!$window(@hashtable.on.unset.command.stack)) window -hns -t10,20,30,40,50,60,70 @hashtable.on.unset.command.stack
  if (!$timer(.hashtable.on.unset.command.stack.despooler)) .timer.hashtable.on.unset.command.stack.despooler -o 0 1 if (!$line($hashtable.on.unset.command.stack,0)) || ($line($hashtable.on.unset.command.stack,1) <= $!ticks) hashtable.on.unset.command.stack.despooler
  window -hn @hashtable.on.unset.command.stack
  return @hashtable.on.unset.command.stack
}
alias -l hashtable.on.unset.command.stack.despooler {
  if ($line($hashtable.on.unset.command.stack,1) <= $ticks) {
    var %line = $ifmatch
    var %table.name = $gettok(%line,4,9)
    var %table.item = $gettok(%line,5,9)
    if ($hget(%table.name,%table.item).unset) {
      var %respool.count = $gettok(%line,2,9)
      inc %respool.count 
      aline $hashtable.on.unset.command.stack [ $calc($ticks + $ifmatch * 1000 * %respool.count) ] $+ $chr(9) $+ %respool.count $+ $chr(9) $+ $gettok(%line,3-,9)
      dline $hashtable.on.unset.command.stack 1
    }
    else {
      .signal -n hashtable.on.unset.command.stack $gettok(%line,1,9) $gettok(%line,2,9) $gettok(%line,3,9) %table.name %table.item $gettok(%line,6-,9)
      dline $hashtable.on.unset.command.stack 1
    }
  }
  if ($line($hashtable.on.unset.command.stack,0)) {
    .timer 1 0 if ($line($hashtable.on.unset.command.stack,1) <= $!ticks) hashtable.on.unset.command.stack.despooler
  }
  else {
    close -@ $hashtable.on.unset.command.stack
    .timer.hashtable.on.unset.command.stack.despooler off
  }
}
;
; Example event below
;
on *:signal:hashtable.on.unset.command.stack: {
  echo -st Hashtable Unset event occured values passed : $1-
  ;Following commands well run the command passed
  ;
  ; scid $3
  ; [ [ $6- ] ]
} 


Damn thats a big post <grin> Sorry should have emailed it to you.

Last edited by DaveC; 28/12/04 11:14 PM.