ron7 has asked for the wisdom of the Perl Monks concerning the following question:

I've just noticed that a string containing square brackets causes a fatal error when configuring a label. Eg:
my $lab = '8 million ways to die (1986)[HD].TAG'; $menu_item->configure(-label=>$lab, ... );
gives:
Tk::Error bad menu entry index "8 million ways to die (1986)[HD]" at / +<path>/i368-linux-thread-multi/Tk.pm line 250 (caused by) Tk::Menu::Item::configure at /<path>/i368-linux-thread-multi/Tk/Menu/I +tem.pm line 63 ...
The actual strings are user supplied file names which are being used in a MRU list so my temporary fix is to change any square braces into brackets for display purposes in the MRU menu list, but if someone can think of a workaround to configure the menu item label with the 'correct' string, I'd appreciate it. BTW, I can create the menu item with the '[]' chars no problem:
$menu_item = $menu_file->command(-label=>$lab, ...);
It's just when I configure an item (using $item->configure(...) duh) that the problem occurs. I'm half inclined to call it a bug?

Replies are listed 'Best First'.
Re: Valid chars for Tk Label
by mr_mischief (Monsignor) on Jan 20, 2011 at 09:11 UTC

    Whenever square brackets in a string I've provided to some unknown code cause an error, I look to see if that code is perhaps interpolating the string at some point. This is especially the case if parentheses or a dollar sign appear earlier in the string. I know you gave the string in single quotes, but perhaps the code evals your string later or something.

    One could chase around through all the various modules relating to Tk and all the various code evals that happen in them. I can tell you that the error comes from entryconfigure() in some way, because that's what is at line 63 of Tk::Menu::Item in the configure sub.

    What I'd try first, though, is to put a backslash in front of each square bracket and see if it helps. Unfortunately in this case it won't.

    What will help is to change around your creation and configuration. In fact, I have a code sample for you in which Tk allows one to configure the label but not create with it. This works:

    #!/usr/local/bin/perl use strict; use warnings; use diagnostics; use Tk; my $top = MainWindow->new( -width => 300, -height => 200 ); my $menu = $top->Menu( -type=> 'menubar', -tearoff => 0 ); $top->configure( -menu => $menu ); my $label = '8 million ways to die (1986) [HD].TAG'; my $item = $menu->Button( -label => 'foo' ); $item->configure( -label => $label, -command => sub {exit()} ); MainLoop;

    If you switch that around to this:

    use strict; use warnings; use diagnostics; use Tk; my $top = MainWindow->new( -width => 300, -height => 200 ); my $menu = $top->Menu( -type=> 'menubar', -tearoff => 0 ); $top->configure( -menu => $menu ); my $label = '8 million ways to die (1986) [HD].TAG'; my $item = $menu->Button( -label => $label ); $item->configure( -command => sub {exit()} ); MainLoop;

    ... then you get a failure on line 63 of Tk::Menu::Item (Tk::Menu::Item version 4.005 with Tk::Menu version 4.023 and Tk version 804.029). Sounds familiar, doesn't it?

    Perhaps you can play with ordering or use what remiah posted.

    I'd say it is a bug, but working around it seems more useful than waiting for it to be fixed. Now, if you wanted to dive in and send a patch to the maintainer that fixes it without breaking anything else, I'm sure that would be appreciated.

      Ok, I'm convinced; it's a bug. The fix does not look hard, but testing that it has not broken anything else is less so. I've never managed to do a cpan install of Tk without using "force" because of the number of errors the build throws up--even though it seems to run fine--so determining if anything new is broke would be painful.

      I've taken remiah's basic approach so the problem is now "avoided" and I get the '[]' chars in my menu items. Life is good.

Re: Valid chars for Tk Label
by Anonymous Monk on Jan 20, 2011 at 05:05 UTC
    I'm half inclined to call it a bug?

    I think it is definitely a bug.

      I saw the same error message when I create menu with $mainwindow->Menu, cascade, and command. When I create menu with Menubutton and change label with entryconfigure, label changed successfully.
      use strict; use warnings; use Tk; my ($mw);#,$menubar,$file,@lables, @label_texts); $mw=MainWindow->new; my $menub=$mw->Menubutton(-text => "File", -menuitems => [ [ 'command' => "New", "-command" => \&newfile, "-underline" => + 0 ], [ 'command' => "Open", "-command" => \&openfile, "-underline" +=> 0 ], [ 'command' => "Save", "-command" => \&savefile, "-underline" +=> 0 ], [ 'command' => "SaveAs", "-command" => \&saveasfile, "-underli +ne" => 4 ] ] )->pack $mw->Button(-text=>'test', -command=>\&test)->pack; MainLoop; sub test{ print "in test\n"; foreach my $i (1 .. 4){ $menub->entryconfigure($i,-label=>'8 million ways to die (1986 +)[HD].TAG' ); } }
      regards.
        Good thinking! Problem for me is I'm trying to do a "standard" looking MRU list in the File menu, including separators, and need to be able to modify the group of menu entries representing the MRU items as users open files, preferably without using magic numbers.

        I've Changed my MRU reordering function to use ->entryreconfigure as suggested and this certainly fixes the problem. Finding the index in the menu where the MRU starts without resorting to magic numbers was not possible, but as the "Save As..." item is followed by a separator, then the first MRU entry, I can get the index for "Save As...", and add 2 to it for the MRU start. I normally hate manifest constants like this, but in this case, I can live with it. Thanks for the suggestion!