paschacroutt has asked for the wisdom of the Perl Monks concerning the following question:

Hi.

Still struggling with some basic things here.

If I do

while (<>){ chomp; my $voir = $_; $voir =~ s/o/"y"/gem; say $voir; }

On a multiline text file, I do get the expected result with the input file modified as desired.

However, if I try this to write resulting lines to a specific file

while (<>){ chomp; my $voir = $_; $voir =~ s/o/"y"/gem; my $Fichiersortie = 'sortie.txt'; open my $sortie, ">", $Fichiersortie or die "Can't open $Fichier +sortie: $!"; say $sortie $voir; close($sortie); }

All I get is a one-line file with the last line (modified) only.

I feel that I don't understand some very basic diamond principle here, something to do with this elusive part of the PRINT doc maybe :

To use FILEHANDLE without a LIST to print the contents of $_ to it, you must use a real filehandle like FH , not an indirect one like $fh .
Could a holy one enlighten me please ?

Replies are listed 'Best First'.
Re: writing to a file when using diamond operator
by choroba (Cardinal) on May 03, 2024 at 14:56 UTC
    The problem is when you open the file for writing: you are reopening it every time you read a line, clobbering its contents and overwriting it with the current line.

    You need to open the file before you start the loop and close it after you finish reading it.

    #!/usr/bin/perl use warnings; use strict; my $fichier_sortie = 'sortie.txt'; open my $sortie, '>', $fichier_sortie or die "Can't open $Fichiersor +tie: $!"; while (<>){ chomp; my $voir = $_; $voir =~ s/o/y/g; say {$sortie} $voir; } close $sortie;

    Update: Fixed a bug (I said "after you finish", but didn't).

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      OK. Thanks Choroba, that makes sense.

      However your code didn't work at first, and reading that you said

      You need to open the file before you start the loop and close it after you finish reading it.

      I tried

      #!/usr/bin/perl use warnings; use strict; my $fichier_sortie = 'sortie.txt'; open my $sortie, '>', $fichier_sortie or die "Can't open $Fichiersor +tie: $!"; while (<>){ chomp; my $voir = $_; $voir =~ s/o/y/g; say {$sortie} $voir; } close $sortie;

      And Yay !

        Of course, you're right. Sorry for the confusion.

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]