newLISP Fan Club

Forum => newLISP in the real world => Topic started by: csfreebird on November 23, 2013, 05:48:57 AM

Title: cannot create a sub class from Tree in another context
Post by: csfreebird on November 23, 2013, 05:48:57 AM
My case is:

1. I have a Sign class

2. In this Sign class, need to create a Class which inherits from Tree, this Class is used for holding key and value pairs. Key is message type, value is corresponding function that is ued to handle the message, that's table-driven design to avoid many if/else statements



My example codes like so:

> (new Class 'Sign)
Sign
> (context Sign)
Sign
Sign> (new Tree 'IncomingMessageHandlers)

ERR: symbol not in MAIN context in function new : IncomingMessageHandlers


How to make my code work?
Title: Re: cannot create a sub class from Tree in another context
Post by: rickyboy on November 23, 2013, 06:25:17 AM
The following will work.


> (context Sign)
Sign
Sign> (new Tree 'MAIN:IncomingMessageHandlers)
IncomingMessageHandlers

However, you should be aware that IncomingMessageHandlers lives in MAIN, not Sign.


Sign> (context MAIN)
MAIN
> MAIN:IncomingMessageHandlers
IncomingMessageHandlers
> Sign:IncomingMessageHandlers
nil

In newLISP, a context can only live in MAIN; there are no "nested" contexts.  So, you can't literally put the IncomingMessageHandlers class "In this Sign class", as you said.  But you could put a reference to IncomingMessageHandlers in Sign to make your Sign method code cleaner.


> (context Sign)
Sign
Sign> ;; You want to write Sign methods with clean code like this.
Sign> (fn () IncomingMessageHandlers)
(lambda () Sign:IncomingMessageHandlers)
Sign> ;; But look what happens when you call the method.
Sign> ((fn () IncomingMessageHandlers))
nil
Sign> ;; A decent solution is to place a reference to
Sign> ;; IncomingMessageHandlers in Sign.
Sign> (define Sign:IncomingMessageHandlers MAIN:IncomingMessageHandlers)
IncomingMessageHandlers
Sign> ;; Now, your "clean code" method does the right thing.
Sign> ((fn () IncomingMessageHandlers))
IncomingMessageHandlers
Title: Re: cannot create a sub class from Tree in another context
Post by: csfreebird on November 23, 2013, 05:59:20 PM
Thank you. :)
Title: Re: cannot create a sub class from Tree in another context
Post by: Lutz on November 24, 2013, 09:20:51 AM
Just make sure that the first time the variable IncomingMessageHandlers is seen in context Sign, it already exists in MAIN as a context name. Symbol trees made with Tree and classes made with Class are global symbols by it's nature. Once a global context symbol exists already, the context you are in will not create a new local variable with the same name unless you force it with the locale context as prefix. When IncomingMessageHandlers then occurs it will automatically be interpreted as the global context symbol.



In the following example when you refer to  IncomingMessageHandlers the second time, it automatically refers to MAIN:IncomingMessageHandlers without necessity of the MAIN  prefix, because IncomingMessageHandlers now exists as a global context symbol.



> (context 'Sign)
Sign
Sign> (new Tree 'MAIN:IncomingMessageHandlers)
IncomingMessageHandlers
Sign> (IncomingMessageHandlers "var" '(a b c))
(a b c)
Sign> (IncomingMessageHandlers "var")
(a b c)
Sign> (symbols)
(a b c)    ; no IncomingMessageHandlers has been created locally
Sign>


Just make sure that the statement (new Tree 'MAIN:IncomingMessageHandlers) is occurring on the top level of context Sign, the first time it occurs and that time it uses the MAIN prefix. Or as an alternative put the Tree creating statement into MAIN  before loading Sign