cannot create a sub class from Tree in another context

Q&A's, tips, howto's
Locked
csfreebird
Posts: 107
Joined: Tue Jan 15, 2013 11:54 am
Location: China, Beijing
Contact:

cannot create a sub class from Tree in another context

Post by 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:

Code: Select all

> (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
Posts: 607
Joined: Fri Apr 08, 2005 7:13 pm
Location: Front Royal, Virginia

Re: cannot create a sub class from Tree in another context

Post by rickyboy »

The following will work.

Code: Select all

> (context Sign)
Sign
Sign> (new Tree 'MAIN:IncomingMessageHandlers)
IncomingMessageHandlers
However, you should be aware that IncomingMessageHandlers lives in MAIN, not Sign.

Code: Select all

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.

Code: Select all

> (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
Posts: 107
Joined: Tue Jan 15, 2013 11:54 am
Location: China, Beijing
Contact:

Re: cannot create a sub class from Tree in another context

Post by csfreebird »

Thank you. :)

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: cannot create a sub class from Tree in another context

Post by 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.

Code: Select all

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

Locked