cannot create a sub class from Tree in another context

Started by csfreebird, November 23, 2013, 05:48:57 AM

Previous topic - Next topic

csfreebird

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?

rickyboy

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
(λx. x x) (λx. x x)

csfreebird

Thank you. :)

Lutz

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