Menu

#231 #auto generates namespaced names

4.0*
closed
6
2013-11-09
2012-09-12
No

According to a message by jonkelly@fastmail.fm on comp.lang.tcl:
> I'm learning/experimenting with ITCL with a view to using it for a project. I'm using 8.6, and the version of ITCL that comes bundled with that.

> So, when I use #auto to auto generate an object name I get back something like classA0, classB1 ... which is fine, except it's not the actual name of the object ... later on when I try to use the object from a different context I get an unknown command error: it appears that the name of the object is the name within the local context when the object was created, something like ::classA::classB1.

> I've worked around this by using a proc to generate a global name at each object creation point, but that's a bit cludgy.

> Is there a way to make the auto name global? Or is there an elegant way to only have the name generation override in one place.

I've looked into it, and I believe that the sprintf() used to generate a name (in the #auto processing in Itcl_HandleClass() in generic/itclClass.c) is not adding a leading namespace qualifier (class names don't start with a ::, so the generated name doesn't, so ItclCreateObject() qualifies with respect to the current namespace). The simplest fix is to adjust the pattern used in the sprintf() to "::%.200s%d" (i.e., add a leading ::) which ensures that objects are always created in the correct namespace. (I'd attach a patch, but it's a trivial alteration and the buffer being written to is definitely large enough...)

The down-side is that the objects will report a fully-qualified name when #auto is used. I don't know if that matters.

Discussion

  • Donal K. Fellows

    • priority: 5 --> 9
    • assigned_to: mmclennan --> wiede
     
  • Ralf Fassel

    Ralf Fassel - 2012-09-12

    We've used something like
    set object [SomeItclObject ::\#auto]
    to work-around this problem.

    Maybe the proposed change should check whether there is already
    a "::" at the start of the name...

     
  • Arnulf Wiedemann

    I think the behaviour is as expected. It should be possible to have classes within the namepace of another class in itcl. If you want the class in the global namespace just use the uplevel command: [uplevel #0 myclass #auto].
    That seems to be compatible with itcl 3.4 as far as I can see.

     
  • Don Porter

    Don Porter - 2012-09-13

    Aren't there two issues here? First, what namespace
    ought the command to be created in. Second whether
    the command name ought to be returned in fully
    qualified form? Take care not to confuse them.

    Returning fully qualified command names is usually
    the right thing to do. Any reason to make an exception
    here?

     
  • Donal K. Fellows

    I was talking about the namespace that the instances were created in when their name is #auto, not the namespace of the class. The issue was that a user (not me!) found it surprising that the instances created *when #auto is used* are in the current namespace (there's a side-problem of the auto-generated instance names not being qualified by default, but there might be good reasons for that when dealing with itk).

    For comparison, TclOO has a different approach to dealing with this: it fully qualifies object names when generating them but lets you override the factory method behavior if you need something else. (That's essential when making megawidgets, as widget path names *must not* be qualifed.)

     
  • Donal K. Fellows

    OK, so it has to work that way. Hmm. Would it be too much to ask for for a little more clarity that this is a consequence of the way it works? If it's catching me out, it's bound to be causing confusion for others.

    An extra example would be a good way of doing this.

     
  • Donal K. Fellows

    • priority: 9 --> 6
     
  • Arnulf Wiedemann

    • status: open --> closed
     
  • Arnulf Wiedemann

    As mentioned already, this is "normal" behaviour also compared to itcl 3.4.

     

Log in to post a comment.