Hi Jeff
You're not alone. I ran into the same problem when working on a
newlisp object system inspired by Python.
It would be really nice to be able to simply write a-bar:foo:some-value. Since I couldn't, I wrote this macro to handle cases when I had contexts inside contexts.
Usage:
To get a value
(eval (nest-ctx a-bar foo some-value))
To do assignment
(set (nest-ctx a-bar foo some-value) 100)
To call a method
((eval (nest-ctx a-bar foo some-function)) arg1 arg2)
Code: Select all
(define-macro (nest-ctx)
(let (_args (args) _ctx nil)
(case (length _args)
(0 nil)
(1 (first _args))
(2 (sym (_args 1) (_args 0)))
(true
(set '_ctx (pop _args))
(while (and (not (empty? _args)) (not (nil? _ctx)))
(set '_ctx (sym (pop _args) _ctx))
)
)
)
)
)
Note that I had to separate the symbols in the arguments, because even passing
a-bar:foo:some-value as an argument to a macro causes the error.
An alternative would be to use periods (".") in place of the colons (":"), but of course that could cause problems if any of the symbols contained a period.
Another option would be to pass
[a-bar:foo:some-value], and parse the different parts out of the symbol.
Then of course you could just pass the string
"a-bar:foo:some-value".
Unfortunately none of these other options seemed very elegant to me, which is why I just kept the arguments separate.