Public methods: verb_templates() Get verb templates verb_info(template) Get {method, remote} local_verb_info(template) Get {method, remote} locally Owner methods: add_verb(template, method, remote) Add a verb del_verb(method) Remove a verb parent root object has_verbs var root name 'has_verbs var has_verbs verbs 0 method init_has_verbs if (caller() != $root) throw(~perm, "Caller is not $root."); verbs = #[]; . method uninit_has_verbs var template; if (caller() != $root) throw(~perm, "Caller is not $root."); verbs = 0; for template in (dict_keys(verbs)) $verb_cache.object_undefined_verb(template); . eval .initialize(); . method verb_templates return dict_keys(verbs); . method add_verb arg template, method, remote; var words, pos; if (!.is_owned_by(sender())) throw(~perm, "Sender is not an owner."); // Check argument types. if (type(template) != 'string) throw(~type, "Template is not a string."); if (type(method) != 'symbol) throw(~type, "Method name is not a symbol."); if (remote != 'remote && remote != 'noremote) throw(~type, "Remote specifier is neither 'remote nor 'noremote"); // Make sure there's exactly one "%this" in the template, as a word by // itself. words = explode(template); if (words[1] == "%this" || words[1] == "*" || words[1] == "*=*") throw(~template, "Template begins with wildcard."); pos = "%this" in words; if (!pos || "%this" in sublist(words, pos + 1)) throw(~template, "Template does not contain exactly one \"%this\"."); // Add the verbs to the dictionary, and notify $verb_cache. verbs = dict_add(verbs, template, [method, remote]); $verb_cache.object_defined_verb(template); . method del_verb arg template; var verb_info; if (!.is_owned_by(sender())) throw(~perm, "Sender is not an owner."); catch ~keynf { verb_info = verbs[template]; verbs = dict_del(verbs, template); $verb_cache.object_undefined_verb(template); } with handler { throw(~verbnf, "No verb with template " + tostr(template) + "."); } . method verb_info disallow_overrides; arg template; var verb_info, anc; if (dict_contains(verbs, template)) return verbs[template]; for anc in (ancestors()) { verb_info = (| anc.local_verb_info(template) |); if (verb_info) return verb_info; } throw(~verbnf, "No verb with template " + template); . method local_verb_info disallow_overrides; arg template; catch ~keynf { return verbs[template]; } with handler { throw(~verbnf, "No verb with template " + template); } .