0

I have a question concerning these two files: 1)

use strict;
use warnings;
use v5.12;
use externalModule;

my $file = "test.txt";

unless(unlink $file){ # unlink is UNIX equivalent of rm

    say "DEBUG: No test.txt persent";

}

unless (open FILE, '>>'.$file) {
    die("Unable to create $file");
 }

say FILE "This name is $file"; # print newline automatically

unless(externalModule::external_function($file)) {
    say "error with external_function";
}

print FILE "end of file\n";

close FILE; 

and external module (.pm)

use strict;
use warnings;
use v5.12;

package externalModule;

sub external_function {

    my $file = $_[0]; # first arguement

    say "externalModule line 11: $file";

    # create a new file handler
    unless (open FILE, '>>'.$file) {
        die("Unable to create $file");
    }

    say FILE "this comes from an external module";

    close FILE;

    1;

}

1; # return true

Now, In the first perl script line 14:

# create a new file handler
unless (open FILE, '>>'.$file) {
    die("Unable to create $file");
}

If I would have

'>'.$file 

instead, then the string printed by the external module will not be displayed in the final test.txt file.

Why is that??

Kind Regards

Marc HPunkt
  • 439
  • 3
  • 14

4 Answers4

3

'>' means open the file for output, possibly overwriting it ("clobbering"). >> means appending to it if it already exists.

BTW, it is recommended to use 3 argument form of open with lexical file-handles:

open my $FH, '>', $file or die "Cannot open $file: $!\n";
choroba
  • 231,213
  • 25
  • 204
  • 289
  • Thanks for the 3 argument function. I can now pass a file handler as an argument and the script works with the '>' version. I would have given you the tick but it did not answer my question of why it was getting overwritten. :( Thanks a lot though! – Marc HPunkt Jan 21 '14 at 15:47
1

If you use >$file in your main function, it will write to the start of the file, and buffer output as well. So after your external function returns, the "end of file" will be appended to the buffer, and the buffer flushed -- with the file pointer still at position 0 in the file, so you'll just overwrite the text from the external function. Try a much longer text in the external function, and you'll see that the last part of it remains, with the first part getting overwritten.

Guntram Blohm
  • 9,667
  • 2
  • 24
  • 31
0

This is very old syntax, and not recommended in modern Perl. The 3-argument version, which was "only" introduced in 5.6.1 about 10 years ago, is preferred. So is using a lexical variable for a file handle, rather than an uppercase bareword.

Anyway, >> means open for append, whereas > means open for write, which will remove any existing data in the file.

cdarke
  • 42,728
  • 8
  • 80
  • 84
0

You're clobbering your file when you reopen it once more. The > means open the file for writing, and delete the old file if it exists and create a new one. The >> means open the file for writing, but append the data if the file already exists.

As you can see, it's very hard to pass FILE back and forth between your module and your program.

The latest syntax is to use lexically scoped variables for file handles:

use autodie;

# Here I'm using the newer three parameter version of the open statement.
# I'm also using '$fh' instead of 'FILE' to store the pointer to the open
# file. This makes it easier to pass the file handle to various functions.
#
# I'm also using "autodie". This causes my program to die due to certain
# errors, so if I forget to test, I don't cause problems. I can use `eval`
# to test for an error if I don't want to die.

open my $fh, ">>", $file;  # No die if it doesn't open thx to autodie

# Now, I can pass the file handle to whatever my external module needs
# to do with my file. I no longer have to pass the file name and have
# my external module reopen the file

externalModule::xternal_function( $fh );
David W.
  • 105,218
  • 39
  • 216
  • 337