Training, Open Source computer languages
PerlPHPPythonMySQLApache / TomcatTclRubyJavaC and C++LinuxCSS 
Search for:
Home Accessibility Courses Diary The Mouth Forum Resources Site Map About Us Contact
 
For 2021 - online Python 3 training - see ((here)).

Our plans were to retire in summer 2020 and see the world, but Coronavirus has lead us into a lot of lockdown programming in Python 3 and PHP 7.
We can now offer tailored online training - small groups, real tutors - works really well for groups of 4 to 14 delegates. Anywhere in the world; course language English.

Please ask about private 'maintenance' training for Python 2, Tcl, Perl, PHP, Lua, etc.
Overwriting files

Posted by Caroline (Caroline), 3 January 2003
Hello

I am writing a GUI to run a number of external commands on behalf of the user.  One of these external commands requires a file a parameter which is the name of a file to be loaded.  This file name lives in a config file.

My GUI works by opening a GetFileOpen widget whic defaults to the location of the file from the config file.  If the user selects a file other than the default (read from the config file), the config file should be updated.

I am having problems updating the config file.  The first time the user selects file is fine, the config file is updated correctly.  The second time the user tries the same opeation (without shutting down the whole GUI) the config file is updated, but is appended to, rather than overwritten.

I'm fairly certain this is also something pretty basic that I just haven't grasped.

I think this is a filehandler buffering issue.  Have tried setting $| to 1, but the problem still continues.

I attach my subroutine for updating the config file.  The subroutine is called every time a file name is selected from my GetOpenFile widget.  

Apologies for great length of subroutine...

C.

sub updateConfig ($$$) {
     
     #$| = 1;
     #print "Arguments to UpdateConfig are:  @_ \n";
     # As a reminder args are:  $fp, $propfile, "salesforcefile="
     
     #read in file line by line and append new line to a var
     open(PROPS, "< $_[1]");
     
     
     
     while ( $line = <PROPS> ) {
           #if the current line matches the one we might want to change
           # build new line and add it to the var created above
           print "$line";
           
           if ( $line =~ /^$_[2]/ ) {
                 
                 print "Matched line is $line\n";
                 #we have found the line we may want to change.  Now split it.
                 @lp = split /=/, $line;
                 
                 print "Split line is $lp[0] and $lp[1]\n";
                 print "I will now compare $lp[1] with $_[0]\n";
                 if ( ! ("$lp[1]" eq "$_[0]") ) {
                       #file does not equal the one selected by the user so replace it
                       $line = $lp[0]."\=".$_[0]."\n";
                       print "Rebuilt line is $line\n";
                       $filecontents .= $line;
                       print "File contents after rebuilding $filecontents\n"
                 } elsif ( $_[0] eq "" ) {
                       $filecontents .= $line;
                       
                 } else {      
                       #lines match, so just update $filecontents
                       $filecontents .= $line;
                 
                 }
                 
           } else {
                 $filecontents .= $line;
           }
                 
     }; # end of while
           
     #when have read whole file, save it in updated format      
     close PROPS;
     
     open( FC, ">$propfile");
                                               
     print FC $filecontents;
                                               
     close FC;
}

Posted by admin (Graham Ellis), 4 January 2003
This certainly isn't an obvious one - at least to me  .

I don't think it's a buffering problem, but you might like to note that $| applies to the currently selected output only - i.e. defaults to STDOUT, and I suspect you might have simply set $| to 1.   Alternative code:
Code:
select FC;
$|=1;
select STDOUT;


I did notice that you opened your file for read using $_[1], but your file for overwrite using $propfile.  Unless I misread something, $propfile looks like a global variable.   Is there any chance that you set it up in your main program to contain something line ">properties.txt", in which case your ">$propfile" would have two ">" characters on it, thus open the file for append.

I do agree that this is one of those problems that you'll say "derr - of COURSE ..." when you spot it, but I'm not convinced that I have spotted it in either two of the comments above.  Please let me know if either of them does help you out, or any other snippets of evidence you have .... if need be, you could write a short test program just to exercise your subroutine .....

Posted by John_Moylan (jfp), 6 January 2003
On an unrelated note I noticed Caroline started her Subroutine with sub updateConfig ($$$)

Question: Why the ($$$)? Is it there just to show how many args are to be passed in ? I have seen this elsewhere.

Just wondered.

jfp


Posted by admin (Graham Ellis), 6 January 2003
It's a "subroutine prototype" - lets you specify as you write your subroutine that it must be called with exactly three scalar parameters - by default, Perl subroutines can be called with any number of parameters and have to check within the subroutine code whether or not they've been called sensibly.

Here's a short piece of code to illustrate:

Code:
#!/usr/bin/perl

sub fred ($$$) {
       my ($one,$two,$three) = @_;
       print $one+$two+$three,"\n";
       }

fred (10,20,30);
fred (10,20);


and here's what happens when you try to run it:



Code:
[localhost:~/jan03] graham% perl subtest
Not enough arguments for main::fred at subtest line 9, near "20)"
Execution of subtest aborted due to compilation errors.
[localhost:~/jan03] graham%


Posted by John_Moylan (jfp), 6 January 2003
Well I never knew that  

I've tended to write a usage sub/object that checks the num of args passed and call die/croak with caller() used in my usage()

Code:
sub usage {

   my ($package, $filename, $line, $subr) = caller(1);
        $Carp::CarpLevel = 2;
        croak "Usage: $subr(@_)";
}

sub some_func {

   usage() unless (@_ == 2 || @_ == 3);
}


You learn something new everyday, must go read about subroutine prototypes in "Programming Perl" now.

jfp
(I keep forgetting to use the code tags on this BB, gone back and fixed it...sorry)

Posted by bdulfer (bdulfer), 14 January 2003
on 01/06/03 at 13:27:12, jfp wrote:
Well I never knew that  

I've tended to write a usage sub/object that checks the num of args passed and call die/croak with caller() used in my usage()

Code:
sub usage {

   my ($package, $filename, $line, $subr) = caller(1);
        $Carp::CarpLevel = 2;
        croak "Usage: $subr(@_)";
}

sub some_func {

   usage() unless (@_ == 2 || @_ == 3);
}


You learn something new everyday, must go read about subroutine prototypes in "Programming Perl" now.


Whether to use function prototypes or not is heavily discussed in the perl community.

Make sure you read more than just what the Camel has to say.

Start here:
http://www.perl.com/pub/a/language/misc/fmproto.html
http://www.perlmonks.org/index.pl?node_id=124339
http://www.perlmonks.org/index.pl?node_id=194637
http://www.perlmonks.org/index.pl?node_id=209928

Posted by admin (Graham Ellis), 15 January 2003
Quote:
Whether to use function prototypes or not is heavily discussed in the perl community.
 
Make sure you read more than just what the Camel has to say.


That's fair comment.  I am very tempted to follow up with a listing of pros v cons on subroutine prototypes, but fear that all I will show bias one way or the other if I do so.   Aw - what the heck  

For - they provide you with a way of checking for some hard-to-spot coding errors without you having to make the tests for yourself in each subroutine.

Against - a bit of an odd implementation.  Also against the
Perl ethos of "Perl assumes you know what you're doing".  With a subroutine prototype, the subroutine author is attempting to protect his caller rather than making this assumption.

I'm shown Perl programs by a wide variety of people who come on training courses, and don't see too many samples that people have inherited that make use of prototypes.   I suspect that's rather more because the original authors of this code haven't come across the prototypes or can't be bothered, rather than a conscious decision not to use them



This page is a thread posted to the opentalk forum at www.opentalk.org.uk and archived here for reference. To jump to the archive index please follow this link.

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2022: Well House Manor • 48 Spa Road • Melksham, Wiltshire • United Kingdom • SN12 7NY
PH: 01144 1225 708225 • FAX: 01144 1225 793803 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho