do newlisp support some callback like method_missing?

Started by shaoyang, August 29, 2015, 09:07:43 AM

Previous topic - Next topic



I am very new to newlisp and not sure if it's good to raise the question to this forum.It could be a very simple question ,but I can't find related part in manuals:

do newlisp support such callbacks (or event) like method_missing ?


For example:

(new Class 'Foo)
(define (Foo:method_missing methodname, args) (dosomthing))
(Foo:helloworld) ; method_missing is expected to be triggered.

when I invoke helloworld function which is not defined in Foo context

 , then the Foo:method_missing will be called.


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:

(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:

> ; 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.