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]