Hello, first of all Happy new year for all! I have a doubt about an object as a parameter and namespaces. For example I have 2 classes:
package require nx
nx::Class create aClass { : public method print {} { puts "I'm an a object: [[self] info name] -> [[self] info parent] " } }
nx::Class create bClass { :property pr:object,required
:method init {} { puts "a_obj print result: " ${:pr} print } }
aClass create a_obj bClass create b_obj -pr a_obj
It works the way it's supposed to work. Now inside the namespace:
namespace eval testNameSpace {
aClass create a_obj1 a_obj1 print bClass create b_obj1 -pr a_obj1 }
This will give me an error, because NX is trying to execute object passed as a parameter in global namespace:
I'm an a object: a_obj1 -> ::testNameSpace
a_obj print result: invalid command name "a_obj1"
My question is, I might be doing something wrong, what is the right way to do it? Or when I pass Object as parameter I need to add namespace manually, why it's not assuming [namespace current]?
Thank you
Hi Maksym!
namespace eval testNameSpace {
aClass create a_obj1 a_obj1 print bClass create b_obj1 -pr a_obj1 }
tl;dr
You need to pass a fully-qualified object (command) name as an argument:
namespace eval testNameSpace { set a_obj1_fq [aClass create a_obj1] a_obj1 print bClass new -pr [namespace which a_obj1] bClass new -pr $a_obj1_fq }
For this purpose, you may capture the fully-qualified object name as the result of the create/new call via a variable (a_obj1_fq); or, you may use [namespace which] to capture the namespace context.
In Tcl, and Tk, the call site is made responsible for resolving or capturing the namespace context; and not the callee. Think of [namespace code ...] and friends. In general, for the callee, there will be ambiguity when reconstructing the original call site, in presence of command traces or different [namespace path ...] settings (or, filters and mixins in XOTcl/ NX); or combinations thereof.
HTH, and Happy New Year to you too,
Stefan
Something in addition to Stefan's reply:
I have simplified your script to the version below. In essence
- statement 1: * an object "o1" (not fully qualified) is created in a namespace "ns1" * the fully qualified command name if "o1" is "::ns1::o1"
- statement 2: - the object name "o1" is provided to property "pr" - The property checks successfully, if "o1" exists as an object in "::ns1" - The value of the property pr is still the string "o1". - After setting this property, the constructor of class B is called. - The constructor of B is executed in the global namespace "::" - In the global namespace "o1" does not exist, therefore the error.
So, passing the object name fully qualified to "-pr" solves the problem. I do agree, that the result is not fully satisfying (the property was checked to be an object, but "suddenly" it cannot be resolved). I might be possible in future versions of nx to convert the passed in object name to a fully qualified object name, but this has to be evaluated carefully.
I won't be able to work on this in the next three weeks, but this is certainly something to consider for future releases. ... For now, please pass the fully qualified name
all the best
-gn
========================================================================== nx::Class create A { :public method print {} { puts "[self] print" } }
nx::Class create B { :property pr:object,required
:method init {} { puts "i am in namespace [namespace current], the value of :pr '${:pr}' is command '[namespace which ${:pr}]'" ${:pr} print } }
namespace eval ns1 { # statement 1 A create o1
# statement 2 B create b1 -pr o1 } ==========================================================================
On 29.12.22 19:37, Maksym Zinchenko wrote:
Hello, first of all Happy new year for all! I have a doubt about an object as a parameter and namespaces. For example I have 2 classes:
package require nx
nx::Class create aClass { : public method print {} { puts "I'm an a object: [[self] info name] -> [[self] info parent] " } }
nx::Class create bClass { :property pr:object,required
:method init {} { puts "a_obj print result: " ${:pr} print } }
aClass create a_obj bClass create b_obj -pr a_obj
It works the way it's supposed to work. Now inside the namespace:
namespace eval testNameSpace {
aClass create a_obj1 a_obj1 print bClass create b_obj1 -pr a_obj1 }
This will give me an error, because NX is trying to execute object passed as a parameter in global namespace:
I'm an a object: a_obj1 -> ::testNameSpace
a_obj print result: invalid command name "a_obj1"
My question is, I might be doing something wrong, what is the right way to do it? Or when I pass Object as parameter I need to add namespace manually, why it's not assuming [namespace current]?
Thank you _______________________________________________ Xotcl mailing list Xotcl@alice.wu.ac.at http://alice.wu.ac.at/mailman/listinfo/xotcl