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

I'm stuck :-( And it's driving me crazy.

I have some perl experience and have created a good few perl CLI scripts in the past. I'm now trying my hand at creating a GUI for one of these scripts. I've decided to use the Tcl::Tk module from CPAN. In fact, I've also tried to use Perl/Tk and struck the same problem.

I want the user to select a file to be moved to a new directory. However, while the file seems to be selected correctly, attempting to move it results in an error.

Here's an excerpt from the code:

#!/usr/local/bin/perl use Tcl::Tk; # Main Window my $int = new Tcl::Tk; my $mw = $int->mainwindow; $mw->title("Move File"); my $frame_border_top = $mw -> Frame(-relief => flat); my $welcome_label = $frame_border_top -> Label(-text => "Welcome\n"); my $select_input_file_label = $mw -> Label(-text=>"Select initial file + to move:"); my $select_input_file_button = $mw -> Button(-text => "Browse", -command => \&open_file ); my $move_button = $mw -> Button(-text => "Move File", -command => \&push_button ); # Geometry Management $frame_border_top -> grid(-row=>1,-column=>1,-columnspan=>2); $welcome_label -> grid(-row=>1,-column=>1,-columnspan=>2); $select_input_file_label -> grid(-row=>2,-column=>1); $select_input_file_button -> grid(-row=>2,-column=>2); $move_button -> grid(-row=>10,-column=>1,-columnspan=>2); $int->MainLoop; # All sub-routines below this point. # Open File Dialogue sub open_file { my $select_input_file = $mw-> getOpenFile(-title=>"Select File +"); # These lines just to see what's going on print "Got: $select_input_file\n"; print "My current directory is: $ENV{PWD}\n"; print "Thinking of doing: mv ${select_input_file} -t /home/phillc\n"; } # Move File sub push_button { system("mv ${select_input_file} -t /home/phillc"); }

Whenever the button is pushed, I get the following error in my terminal:

mv: missing file operand
Try `mv --help' for more information.

I'm sure that I am missing something very obvious but don't know what. Any pointers most appreciated.

Replies are listed 'Best First'.
Re: Tcl::Tk getOpenFile Not Working - Missing File Operand
by almut (Canon) on Feb 20, 2008 at 23:51 UTC

    Looks like you're not setting $selected_file anywhere, so you move command becomes "mv -t /home/phillc" (i.e. source arg missing).

    Generally, if some system command isn't working as you expect, it's always a good idea to just print it out — in many such cases it's immediately evident what the problem is...

Re: Tcl::Tk getOpenFile Not Working - Missing File Operand
by zylot (Initiate) on Feb 21, 2008 at 00:10 UTC
    in push_button sub, it looks like you are using ${selected_file} instead of $select_input_file


    Cheers
    Zylot
Re: Tcl::Tk getOpenFile Not Working - Missing File Operand
by phillc (Novice) on Feb 21, 2008 at 00:24 UTC
    Thank you for pointing that out. Indeed it was a mistake.

    However, I have now changed the variable call to ${select_input_file} (and updated my original post), but the error of "missing operand" still persists.

      As you have it, the scope of the lexical variable my $select_input_file is limited to the sub open_file. A quick hack would be to declare it outside of the sub, so it becomes globally visible.

      BTW, using strictures would have warned you that $select_input_file within push_button() is not what you thought it is...

      Your "sub open_file" declares a LOCAL lexical my $select_input_file.

      Your "push_button" gets a different (uninitialized) variable with the same name.

      Lesson : always use strict;

           "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

Re: Tcl::Tk getOpenFile Not Working - Missing File Operand
by phillc (Novice) on Feb 21, 2008 at 00:31 UTC
    I tried skinning the cat in a different way and made my last subroutine the following:
    sub push_button { $selected_file = "mv ${select_input_file} -t /home/phillc"; system($selected_file); }
    Unfortunately, result was the same error.
      Hmmm .. how can I repeat myself without appearing offensive/patronizing ?
      Please re-read my previous response, and

      REMOVE the "my" from " my $select_input_file" inside "sub open_file".

           "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

Re: Tcl::Tk getOpenFile Not Working - Missing File Operand
by phillc (Novice) on Feb 21, 2008 at 07:18 UTC
    Thanks for your helpful response almut. Thanks also for the strict lesson NetWallah.

    I'm now using strict and have declared variables globally. The application works as expected.

    For completion, here's the working code:

    #!/usr/local/bin/perl use Tcl::Tk; use strict; # Main Window my $int = new Tcl::Tk; my $mw = $int->mainwindow; $mw->title("Move File"); my $frame_border_top = $mw -> Frame(-relief => "flat"); my $welcome_label = $frame_border_top -> Label(-text => "Welcome\n"); my $select_input_file_label = $mw -> Label(-text=>"Select initial file + for conversion:"); my $select_input_file_button = $mw -> Button(-text => "Browse", -command => \&open_file ); my $move_button = $mw -> Button(-text => "Move File", -command => \&push_button ); # Geometry Management $frame_border_top -> grid(-row=>1,-column=>1,-columnspan=>2); $welcome_label -> grid(-row=>1,-column=>1,-columnspan=>2); $select_input_file_label -> grid(-row=>2,-column=>1); $select_input_file_button -> grid(-row=>2,-column=>2); $move_button -> grid(-row=>10,-column=>1,-columnspan=>2); $int->MainLoop; # Declare global subroutine variables my $select_input_file; my $selected_file; ### All sub-routines below this point. ### # Open file dialogue sub open_file { $select_input_file = $mw-> getOpenFile(-title=>"Select File"); # These lines just to see what's going on print "Got: $select_input_file\n"; print "My current directory is: $ENV{PWD}\n"; print "Thinking of doing: mv ${select_input_file} -t /home/phillc\n"; } # Push button and move file sub push_button { $selected_file = "mv ${select_input_file} -t /home/phillc"; system($selected_file); }
    I'd like to thank the Wisdom of the Monks for assisting with this solution.