Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Bareword "SEEK_END" not allowed while "strict subs" in use

by thanos1983 (Pilgrim)
on May 09, 2014 at 00:49 UTC ( #1085523=perlquestion: print w/ replies, xml ) Need Help??
thanos1983 has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,

I am trying to become familiar with flock but it seems that I am getting an unexpected error:

Bareword "SEEK_END" not allowed while "strict subs"

I am searching online, and I can not found a solution to my error. The syntax looks correct but where I am going wrong?

Working sample of my code is provided below:

#!/usr/bin/perl use strict; use warnings; use Fcntl qw(:flock); $| = 1; # Flush the output my $file = "perl.txt"; open( FH , "+<" , $file ) or die "Unable to open '".$file."' - $!\n"; flock( FH , LOCK_EX ) or die "Could not lock '".$file."' - $!\n"; =notes +< open a file for updating without truncating it. (truncating means empties the file before opening it. flock exclusive lock or FH , 2 but better LOCK_EX because, might not be the right number on all operating systems. =cut seek( FH , 0 , SEEK_END ) or die "Cannot seek - $!\n"; # put the pointer at the end of file for writing. truncate( FH , 0 ) or die "Cannot truncate - $!\n"; print FH "This is line-1."\n"; print FH "This is line-2."\n"; close(FH) or die "Could not write '".$file."' - $!\n";

Well since I am asking a posting this question I hope that you do not mind to ask a few other things about flock that are not so clear to me yet.

I have read the tutorial Perl truncate Function and I am not 100% sure if I am using correctly the truncate() function.

I am confused with the part that (reduces) the size of the file. Maybe this is a very basic question and answer but I can not understand excactly what it does. I visit also truncate and a dew other wesites, but again it is not clear to me.

What I understand is that we are using it to clean the file after from the indicated point fseek() to prepate the file for writing.

Thanks everyone for the time and effort reviewing my question.

Best Regards,

Thanos

Comment on Bareword "SEEK_END" not allowed while "strict subs" in use
Select or Download Code
Re: Bareword "SEEK_END" not allowed while "strict subs" in use (explicit)
by tye (Cardinal) on May 09, 2014 at 00:56 UTC

    Instead of being relatively coy about what you are importing:

    use Fcntl qw(:flock);

    Just be explicit, and the problem goes away:

    use Fcntl qw< LOCK_EX SEEK_END >;

    (And your code becomes clearer.)

    - tye        

      To: tye,

      Damn I forgot this part, completely. Thanks for pointing out.

      Can you help me also unserstand a bit the truncate() part?

      I have some questions and I do not know if I am correct or wrong, since is the first time that I am applying that. I have written a short exaplanation on my initial question at the end.

      Again thank you for your time and effort

Re: Bareword "SEEK_END" not allowed while "strict subs" in use (truncate)
by tye (Cardinal) on May 09, 2014 at 15:13 UTC

    Your use of truncate() doesn't make sense in context.

    As noted in the comment, seek( FH, 0, SEEK_END ) will seek to the end of the file. But truncate( FH, 0 ) will then truncate the file to size 0. This means your seek position will now be past the end of the file (unless the file had already been empty). This means that when you next write to the file, nil bytes will be used to fill the first part of the file up to the point of your seek position.

    I could see a point of opening the file in a manner that doesn't truncate for the explicit purpose of only truncating the file after you have obtained a lock. In such a case, I don't see how seeking to the end of the file would make sense.

    I could also see the point of seeking (perhaps by reading) to a point in the file and then truncating from that point on before writing. In such a case, you would not pass 0 as the 2nd argument to truncate(). And that only makes sense if the seek point might not be the current end of the file.

    I hope that helps to clarify things for you.

    See also truncate,2.

    - tye        

      To: tye,

      Ok, starting to make more sense.

      My plan was to use flock() to lock the file while my process will be either reading or writting to it. I want to avoid 2 processes together reading and writting simultaneously which will result on overlaping.

      So my plan was to lock the file seek to the end of the file so I can write the next part of my output, close the file and allow the next process to write on it.

      I was under the impression that I have to use truncate to empty the rest of the file at the end, to make sure there is nothing left besfore start writting.

      I got this idea from the tutorial File Locking where they use both:

      seek(MYFILE, 0, 0); truncate(MYFILE, 0);

      This is my part of confusion.

Re: Bareword "SEEK_END" not allowed while "strict subs" in use
by Monk::Thomas (Beadle) on May 13, 2014 at 09:00 UTC
    open( FH , "+<" , $file ) or die "Unable to open '".$file."' - $!\n";

    Btw. you really should use lexical variables instead of barewords for your filehandles. Especially if you use something obvious like 'FH'.

    open( my $fh , "+<" , $file ) or die "Unable to open '".$file."' - $!\n";
    (and with slightly improved style)
    open my $fh, '+<', $file or die "Unable to open '$file': $!\n";

    Using bareword symbols to refer to file handles is particularly evil because they are global, and you have no idea if that symbol already points to some other file handle. You can mitigate some of that risk by localizing the symbol first, but that's pretty ugly. Since Perl 5.6, you can use an undefined scalar variable as a lexical reference to an anonymous filehandle. Alternatively, see the IO::Handle or IO::File or FileHandle modules for an object-oriented approach.

      Using bareword symbols to refer to file handles is particularly evil because they are global, and you have no idea if that symbol already points to some other file handle. You can mitigate some of that risk by localizing the symbol first

      It isn't particularly hard to grep for "FH" being used elsewhere in the current package. And local doesn't actually mitigate that risk much unless you only use the file handle for the duration of some short-lived subroutine (and there are no subroutines in the original code).

      Oh, and it was 5.6.1 where "open my $fh" became supported. :)

      - tye        

        *Erm* It's not about your package. It suffices if some library (which you may not even call directly) is using FH to read/write a file. Suddenly your file descriptor points to some totally different file/is closed/open for writing instead of reading or something completely different.

        I'm sure I don't have enough time to debug something like this. Do you?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1085523]
Approved by toolic
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (7)
As of 2014-10-26 08:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (152 votes), past polls