spurt and array question

Hi All,

I am writing out an array of text lines to a file. I just can't help but thinking I am doing it the hard way.

    unlink( $Leafpadrc );
    for @LeafpadrcNew -> $Line  { spurt( $Leafpadrc, $Line ~ "\n", 
:append ); }

If I spurt the array, it converts the array into a single text line.

The test file looks like this:

         ./.config/leafpad/leafpadrc
         $ cat leafpadrc
         0.8.18.1
         500
         190
         Monospace 12
         1
         1
         0

Your thoughts?

-T

-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Computers are like air conditioners.
They malfunction when you open windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0
perl6
11/14/2020 7:59:14 AM
📁 perl.perl6.users
📃 1545 articles.
⭐ 0 followers.

💬 14 Replies
👁️‍🗨️ 117 Views

Unless I misunderstand, why doesn't this work:

    my $fh = open $Leafpadrc, :w;
    $fh.say($_) for @Leafpadrc;

-Tom
0
tom
11/14/2020 11:15:41 AM
Some alternatives:

  $Leafpadrc.spurt(@LeafpadrcNew.join($Leafpadrc.nl-out));

  $Leafpadrc.put($_) for @LeafpadrcNew;

-- 
    Dakkar - <Mobilis in mobile>
    GPG public key fingerprint = A071 E618 DD2C 5901 9574
                                 6FE2 40EA 9883 7519 3F88
                        key id = 0x75193F88
0
dakkar
11/14/2020 11:59:48 AM
The purpose of `spurt` is to:
1. open a NEW file to write to
2. print a single string
3. close the file

If you are calling `spurt` more than once on a given file, you are doing it wrong.
If you give `spurt` an array, you are probably doing it wrong; unless you want the array turned into a single string first.

`spurt` is the dual of `slurp`.

The purpose of `slurp` is to:
1. open an existing file to read from
2. read the whole file into a single string
3. close the file

That is they are only short-cuts for a simple combination of operations.

If you are opening a file for only the express purpose of reading ALL of its contents into a SINGLE STRING, use `slurp`.
If you are opening a file for only the express purpose of writing ALL of its contents from a SINGLE STRING, use `spurt`.

If you are doing anything else, use something else.

---

Assuming you want to loop over a bunch of strings to print to a file, use `open` and `print`/`put`/`say`. This is also faster than calling `spurt` more than once because you only open and close the file once.

If you want there to be only one call, turn your array into the appropriate single string first.
0
b2gills
11/14/2020 2:00:22 PM
> The purpose of `spurt` is to:
> 1. open a NEW file to write to
> 2. print a single string
> 3. close the file
>
> If you are calling `spurt` more than once on a given file, you are doing it wrong.

You are forgetting that spurt comes with an `:append` option.

> If you give `spurt` an array, you are probably doing it wrong
> unless you want the array turned into a single string first.

Ya, doing things the hard way.
0
perl6
11/14/2020 7:07:20 PM
Maybe this is what you want:

my @a = 1,2,3;
spurt('test', @a.join("\n") ~ "\n");  # join doesn't add the last "\n"

Or the equivalent

'test'.IO.spurt: @a.join("\n") ~ "\n";

-- 
Fernando Santagata
0
nando
11/14/2020 7:22:30 PM
On 2020-11-14 03:59, Gianni Ceccarelli wrote:
> $Leafpadrc.put($_) for @LeafpadrcNew;

Cannot resolve caller print(Str:D: BOOTStr); none of these signatures match:
     (Mu: *%_)
   in sub RunReport at ./XferParts.pl6 line 229

229: $Leafpadrc.put($_) for @LeafpadrcNew;

-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Computers are like air conditioners.
They malfunction when you open windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0
perl6
11/14/2020 7:41:12 PM
Actually no I'm not forgetting that spurt comes with an `:append` option.

That is a slightly different use case. It is where you are appending to an existing file once, and then never touching it again.

(Or maybe you might be touching it again in a few hours.)

---

Given that this is what you wrote:

    unlink( $Leafpadrc );
    for @LeafpadrcNew -> $Line  { spurt( $Leafpadrc, $Line ~ "\n", :append
); }

I want to know how this is the hard way:

    given $Leafpadrc.IO.open(:w) {
        for @LeafpadrcNew -> $Line  { .put: $Line }
        .close;
    }

or

    given $Leafpadrc.IO.open(:w) -> $*OUT {
        for @LeafpadrcNew -> $Line  { put $Line }
        $*OUT.close;
    }

or

    given $Leafpadrc.IO.open(:w) -> $*OUT {
        .put for @LeafpadrcNew;
        $*OUT.close;
    }

or

    given $Leafpadrc.IO.open(:w, :!out-buffer) -> $*OUT {
        .put for @LeafpadrcNew;
    }
0
b2gills
11/14/2020 7:51:25 PM
    unlink( $Leafpadrc );
    $Leafpadrc.IO.open( :w );

Neither of these two actually updates the file.

    for @LeafpadrcNew -> $Line  { put( $Leafpadrc, $Line ); }
    for @LeafpadrcNew -> $Line  { $Leafpadrc.put( $Line ); }
0
perl6
11/14/2020 7:59:20 PM
That is the way around the issue.

But my question is why can I not put the \n in the variable?
0
perl6
11/14/2020 8:01:57 PM
I was saying I was doing it the hard way, not you.

Wonderful examples.

Thank you!
0
perl6
11/14/2020 8:03:38 PM
What do you mean by putting the \n in the variable?
Is it anything like this?

my @a "1\n", "2\n", "3\n";
'test'.IO.spurt(@a);

or this?

my @a <a b c>;
'test'.IO.spurt(@a ~ "\n");


Mind that the array is first converted into a string and its elements are joined together with an interleaving space

--
Fernando Santagata
0
nando
11/14/2020 9:39:15 PM
> What do you mean by putting the \n in the variable?

$ p6 'my @x = <<aaa\n bbb\n ccc\n>>; for @x {"$_".print};'
aaabbbccc

Why are the \n's not being resolved in the above?

Why do I have to add an \n to the print line?

$ p6 'my @x = <<aaa\n bbb\n ccc\n>>; for @x {"$_\n".print};'
aaa
bbb
ccc

Oh I see, because they are not actually in the cell:

$ p6 'my @x = <<aaa\n bbb\n ccc\n>>; dd @x'
Array @x = ["aaa", "bbb", "ccc"]
0
perl6
11/14/2020 11:25:18 PM
Oh, now I see: you were asking that question in another thread.

<<>> is equivalent to qq:ww:v as mentioned here:

https://docs.raku.org/syntax/%3C%3C%20%3E%3E#index-entry-%3Aval_%28quoting_adverb%29

and as stated here:

https://docs.raku.org/language/quoting

the adverb :ww splits the string into words using whitespace characters as separators.

Now, being "\n" a whitespace character, your string <<aaa\n bbb\n ccc\n>> was split in three parts ("aaa", "bbb", "ccc") with no whitespace characters in them.
0
nando
11/15/2020 7:56:53 AM
I was asking why the \n came out literal in another thread. It did not help I made a syntax boobo.

I never got the other ways of writing out the array to work either.
0
perl6
11/15/2020 7:59:47 AM
Reply:
(Thread closed)