This reminds me on Smalltalk's #messageNotUnderstood selectors.
Here is something similar for newLISP FOOPs; due to not having messages, but function calls, there is the renaming to
callNotUnderstood.
After loading cnu.lsp:
Code: Select all
(new Class 'Foo)
(context Foo)
(define (fun)
(string "FOOP: " (self) ", call: " 'fun ", arguments: " (args)))
(define (callNotUnderstood symbol arguments)
(string "FOOP: " (self) ", call: " symbol " *** not understood ***,"
" arguments: " arguments))
(context MAIN)
;;
(define (call-sym-foop Symbol foop)
(if (not (symbol? Symbol))
(throw-error "1. argument: symbol expected."))
(letn ((ctx (and (list? foop) foop (foop 0)))
(symbol (if (context? ctx) (sym Symbol ctx))))
(if (not (context? ctx))
(throw-error "2. argument: FOOP expected."))
(if (lambda? (eval symbol))
(eval (append (expand '(: Symbol foop)) (args)))
(:callNotUnderstood foop symbol (args)))))
; there may be following session:
Code: Select all
> ; create an instance of Foo:
> (set 'foo (Foo "I'm a foo."))
(Foo "I'm a foo.")
> ; calling Foo:fun for instance foo by:
> (:fun foo 1 2 3)
"FOOP: (Foo \"I'm a foo.\"), call: fun, arguments: (1 2 3)"
> ;;
> ; call existing Foo:fun indirectly:
> (call-sym-foop 'fun foo 1 2 3)
"FOOP: (Foo \"I'm a foo.\"), call: fun, arguments: (1 2 3)"
> ; try to call non-existing Foo:funNotThere :
> (call-sym-foop 'funNotThere foo 1 2 3)
"FOOP: (Foo \"I'm a foo.\"), call: funNotThere *** not understood ***, arguments: (1 2 3)"
>
Foo:callNotUnderstood is the place for handling the case of not having some func in Foo context; under the precondition, that func will be called (more) indirectly by using
call-sym-foop: taking func symbol, FOOP instance and optional more as arguments.
This would also work for other FOOPs; e.g. Bar:callNotUnderstood would be called for an instance of Class Bar, if some Bar func is missing.
Note: There may be more elegant ways to reach this kind of behavior.