Append a record to the end of a text file

This is kind of silly as it takes a string, converts it to a record, and then instantly converts it back to a string to write out to a file. Most of the "record handling" code is just demonstrating a possible way to store records in memory. It really has nothing to do with appending a string to a file.

class record {
    has $.name;
    has $.password;
    has $.UID;
    has $.GID;
    has $.fullname;
    has $.office;
    has $.extension;
    has $.homephone;
    has $.email;
    has $.directory;
    has $.shell;

    method gecos { join ',', $.fullname, $.office, $.extension, $.homephone, $.email }

    method gist {
        join ':',
        $.name,
        $.password,
        $.UID,
        $.GID,
        self.gecos,
        $.directory,
        $.shell;
    }
};

my $fname = 'foo.fil';

given $fname.IO.open(:w) { .close }; # clear file

sub append ($file, $line){
    my $fh = $file.IO.open(:a) or fail "Unable to open $file";
    given $fh {
        # Get a lock on the file, waits until lock is active
        .lock;
        # seek to the end in case some other process wrote to
        # the file while we were waiting for the lock
        .seek(0, SeekType::SeekFromEnd);
        # write the record
        .say: $line;
        .close;
    }
}

sub str-to-record ($str) {
    my %rec = <name password UID GID fullname office extension
      homephone email directory shell> Z=> $str.split(/<[:,]>/);
    my $user = record.new(|%rec);
}

for
  'jsmith:x:1001:1000:Joe Smith,Room 1007,(234)555-8917,(234)555-0077,[email protected]:/home/jsmith:/bin/bash',
  'jdoe:x:1002:1000:Jane Doe,Room 1004,(234)555-8914,(234)555-0044,[email protected]:/home/jdoe:/bin/bash'
-> $line {
        my $thisuser = str-to-record $line;
       $fname.&append: $thisuser.gist;
}

put "Last line of $fname before append:";
put $fname.IO.lines.tail;

$fname.&append: str-to-record('xyz:x:1003:1000:X Yz,Room 1003,(234)555-8913,(234)555-0033,[email protected]:/home/xyz:/bin/bash').gist;

put "Last line of $fname after append:";
put $fname.IO.lines.tail;

Output:

Last line of foo.fil before append:
jdoe:x:1002:1000:Jane Doe,Room 1004,(234)555-8914,(234)555-0044,[email protected]:/home/jdoe:/bin/bash
Last line of foo.fil after append:
xyz:x:1003:1000:X Yz,Room 1003,(234)555-8913,(234)555-0033,[email protected]:/home/xyz:/bin/bash

Note that advisory locks do not prevent some other program (if it doesn't use flock) from unexpectedly writing to the file.