Thoughts on namespaces in Perl/Tk

Rob Seegel <[email protected]>
Newsgroups gmane.comp.lang.perl.tk
Message-ID <[email protected]>
This post has to do with issues I've run into regarding  namespace in 
Perl/Tk. I am curious to see if others have run into the same issues, 
and if so, how those issues were resolved.

One thing that has been problematic for me in Perl/Tk is the use of 
namespaces. When designing a new module there is nothing that says I 
can't define any of the following packages:

package Tk::MyWidget;
package Tk::MyApp::MyWidget;
package MyApp::MyWidget;

The problem is that it's not really the package that's the important 
thing, it's the following line, that you will find in pretty much every 
Tk widget.

Tk::Widget->Construct('MyWidget");

Which will dynamically create a method called "MyWidget" in the 
Tk::Widget base class, that means that all Widgets that extend 
Tk::Widget can construct an instance of MyWidget.. If you only want your 
widget to be created by a Frame-based widget (MainWindow, Toplevel, 
Frame, and many composites), then the line would be:

Tk::Frame->Construct("MyWidget");

This is the magic that allows the following convenient syntax:

my $mw = MainWindow->new;
my $widget = $mw ->MyWidget( -option => $value)->pack;

which is much for concise than:

my $mw = MainWindow->new();
my $widget = Tk::MyApp::MyWidget->new($mw, -option => $value)->pack;

The downside of the Construct method is that it essentially flattens out 
any hierarchy that may exist and opens the door for conflicts in 
namespaces. Let's say I decide to create my own version of an existing 
widget, like Tree.

package Tk::MyWidget::Tree;
Tk::Widget->Construct("Tree");
[rest of module snipped]

There is already a Tk::Tree widget, and depending on which one I "use" 
first in my application, the Tk::Widget::Tree method that one creates 
will be overridden by the other, which can be problematic. The real 
issue though is that there should be a way to prevent one from getting 
confused for the other. Far and away the easiest way this is done is by 
using a different name.

The package Tk::MyWidget::Tree might use any of the following:

Tk::Widget->Construct("MyWidgetTree");
Tk::Widget->Construct("MyWidget-Tree");
Tk::Widget->Construct("MWTree");

Which would allow me to call the following respectively:

my $w = $mw->MyWidgetTree;
my $w = $mw->MyWidget-Tree;
my $w = $mw->MWTree;
my $w = $mw->MyTree;

Which raises the question, why call the package Tree to begin with, 
regardless of which package it's in? Isn't this just asking for trouble? 
Perhaps. Why not come up with another name such as TreeView, MyTree, 
CanvasTree, or something like that?  I could but sometimes a simple name 
sums up the functionality so well, that it's a shame not to be able to 
reuse it, even if it's in another namespace. If there is a widget called 
Tk::Tree in the main distribution, and I see another package called 
Tk::MyWidget::Tree then I might think that the two deliver similar 
functionality. On the other hand, maybe it would just be confusing...

I briefly looked into doing something  where I overrode Construct in 
CWidget, which  is a subclass of Tk::Frame. The goal was to allow me to 
use the following code:

package CWidget::Tree;
CWidget->Construct("Tree");
[code snipped]

And then be able to do something like this:

$mw->CWidget::Tree;

This is subtly different from the Tk::Widget, because it does not create 
a Tree
method in Widget, it creates it in CWidget. It is slightly uglier, but 
it is very clear whenever it is created, that it is different from 
Tk::Tree. The nice thing is that both Tk::Tree, and CWidget::Tree could 
be used within the same code. without interfering with the other.

One problem I had with this approach, was that originally CWidget was 
Tk::CWidget, and all of the Composites in the collection were under 
CWidget. This would lead to the following:

$mw->Tk::CWidget::Tree;

Which isn't horrible, but I preferred: $mw->CWidget::Tree. My reasoning 
was this: If I had a widget under the Tk package that could be created 
by name, then it would stand to reason that a widget one directory under 
Tk be created by created by adding the package name. This is naive I 
know, and I realize why it doesn't work this way, but it feels intuitive 
nonetheless.

At any rate -- that's just a few of my rambling thoughts about it.  I'd 
like to see what others think.

Rob



-++**==--++**==--++**==--++**==--++**==--++**==--++**==
This message was posted through the Stanford campus mailing list
server.  If you wish to unsubscribe from this mailing list, send the
message body of "unsubscribe ptk" to [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.