Page 1 of 1

do newlisp support some callback like method_missing?

PostPosted: Sat Aug 29, 2015 4:07 pm
by shaoyang
Hi,
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:
Code: Select all
(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.

Re: do newlisp support some callback like method_missing?

PostPosted: Fri Oct 02, 2015 6:56 pm
by hartrock
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.