Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you append to a file in Perl 6?

Tags:

io

raku

I was trying this and a few other things but it truncates the file each time:

my $file = 'primes.txt';
sub MAIN ( Int:D $low, Int:D $high where * >= $low ) {
    unless my $fh = open $file, :w, :append {
        die "Could not open '$file': {$fh.exception}";
    }

    for $low .. $high {
        $fh.put: $_ if .is-prime;
    }
}

Changing this to open $file, :a also seems to truncate the file. This is 2018.04 on macOS.

like image 506
brian d foy Avatar asked Jun 12 '18 16:06

brian d foy


2 Answers

Perl6 &open semantics are based on POSIX, with the following mapping:

:mode<ro>  --> O_RDONLY
:mode<wo>  --> O_WRONLY
:mode<rw>  --> O_RDWR
:create    --> O_CREAT
:append    --> O_APPEND
:truncate  --> O_TRUNC
:exclusive --> O_EXCL

For convenience, the following shortcuts are provided:

:r      --> :mode<ro>
:w      --> :mode<wo>, :create, :truncate
:x      --> :mode<wo>, :create, :exclusive
:a      --> :mode<wo>, :create, :append
:update --> :mode<rw>
:rw     --> :mode<rw>, :create
:rx     --> :mode<rw>, :create, :exclusive
:ra     --> :mode<rw>, :create, :append

Not all platforms supported by Rakudo (eg Windows, JVM, not even POSIX itself) support all possible combinations of modes and flags, so only the combinations above are guaranteed to behave as expected (or are at least supposed to behave that way).

Long story short, a simple :a absolutely should do what you want it to do, and it does so on my Windows box. If it really truncates on MacOS, I'd consider that a bug.

like image 125
Christoph Avatar answered Nov 17 '22 17:11

Christoph


Using :mode<wo>, :append works although this wouldn't be the first thing most people are going to reach for when they see :a:

my $file = 'primes.txt';
sub MAIN ( Int:D $low, Int:D $high where * >= $low ) {
    unless my $fh = open $file, :mode<wo>, :append {
        die "Could not open '$file': {$fh.exception}";
        }

    for $low .. $high {
        $fh.put: $_ if .is-prime;
        }

    $fh.close;
    }

The problem is that Perl 6 tends to silently ignore named parameters. It also looks like roast/open.t doesn't actually test this stuff through the user interface. It plays various tricks that should probably be unrefactored.

like image 24
brian d foy Avatar answered Nov 17 '22 19:11

brian d foy