Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Bugfixing Old Code

by cluelessPerlMan (Initiate)
on Jul 22, 2021 at 15:27 UTC ( [id://11135302]=perlquestion: print w/replies, xml ) Need Help??

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

Dear Monks, I apologize I am completely clueless with Perl and as a favor have opted to help fix an old simulation model. The developer preceding me decided to use Perl to parse some data files, and for some reason it is no longer compiling and throwing errors. I am in the process of teaching myself Perl but any advice would be greatly appreciated. The errors being thrown: Experimental push on scalar is now forbidden at ../../plot_TTTDIA.pl line 44, near "@header)" Experimental push on scalar is now forbidden at ../../plot_TTTDIA.pl line 69, near "@twenty_SFs)" Execution of ../../plot_TTTDIA.pl aborted due to compilation errors.

#!/usr/bin/perl use CGI::Carp qw(fatalsToBrowser); use strict; use warnings; use feature 'say'; use List::Util 'max'; ## If the @left curve passes through the @right curve, ## replace the values that pass with 'nan'. sub trim_curves { my @left = @{shift @_}; # array of references my @right = @{shift @_}; my $rows = shift @_; # integer my $y = $rows - 1; # Start reading from the tail of the data first. for (my $i = $y; $i >= 1; $i--) { # $i = 0 is the header if (${$left[$i]} > ${$right[$y]}) { ${$left[$i]} = 'nan'; $y--; } else { # If @left is no longer greater, stop. last; } } return; } ## Grab useful information from the $infile and put it ## into a column-oriented, tab-separated format. sub parse_file { my $infile = shift @_; my $outfile = shift @_; open (my $in, '<', $infile) || die "Can't open $infile: $!"; open (my $out, '>', $outfile) || die "Can't open $outfile: $!"; # Build TTTPLOT data my @TTTPLOT; # 2D array my @header = ('Temperature', 'StartFerrite', 'StartPeralite', 'Sta +rtBainite', 'MaxSF'); for (my $i = 1; $i <= 20; $i++) { push @header, "SF($i)"; } push /@TTTPLOT, /@header; # Current row index of @TTTPLOT my $index = 1; # Index of 0 is the header above # Read the file's header data my $grade = <$in>; my $chemcomp = <$in>; my $grain = <$in>; my $asymptotes = <$in>; # Read the file's per-temperature data while(<$in>) { # Split on multiple spaces using regex captured matches my @temp_and_starts = $_ =~ /[^\s +]+/g; my @last_AT_fracs = <$in> =~ /[^\s +]+/g; my @twenty_SFs = (<$in> . <$in> . <$in> . <$in>) =~ /[^\s +]+/g; my $max_SF = max @twenty_SFs; # Build the @TTTPLOT row $TTTPLOT[$index]->[0] = $temp_and_starts[0]; $TTTPLOT[$index]->[1] = $temp_and_starts[1]; $TTTPLOT[$index]->[2] = $temp_and_starts[2]; $TTTPLOT[$index]->[3] = $temp_and_starts[3]; $TTTPLOT[$index]->[4] = $max_SF; push $TTTPLOT[$index], @twenty_SFs; $index++; } # Trim the overlapping tails off each combination of curves my @Fs = map \$_->[1], @TTTPLOT; # create an array of references my @Ps = map \$_->[2], @TTTPLOT; my @Bs = map \$_->[3], @TTTPLOT; trim_curves(\@Fs, \@Ps, $index); # check for ferrite greater than +pearlite trim_curves(\@Fs, \@Bs, $index); # check for ferrite greater than +bainite trim_curves(\@Ps, \@Bs, $index); # check for pearlite greater than + bainite # Output each row to the output file foreach my $row (@TTTPLOT) { say $out (join "\t", @{$row}); # tab-separated } close $in; close $out; return; } parse_file("./TTTPLOT.DAT", "./TTTPLOT_PARSED.DAT");

This parsed file is never being generated obviously which is why none of the data is being graphed.

Thank you to anyone who can provide some insight, I am sorry I have little to no experience working with Perl.

Replies are listed 'Best First'.
Re: Bugfixing Old Code
by hippo (Bishop) on Jul 22, 2021 at 15:46 UTC

    Welcome to the Monastery, cluelessPerlMan.

    Are you sure this code is the one you are attempting to run?

    push /@TTTPLOT, /@header;

    That does not look like valid perl. I suspect that the actual code has backslashes where you have slashes. In which case you should not be attempting to dereference @TTTPLOT. Use something like this instead:

    push @TTTPLOT, \@header;

    If that makes the first error vanish, then you can also try changing line 69 to

    push @{$TTTPLOT[$index]}, \@twenty_SFs;

    🦛

Re: Bugfixing Old Code
by choroba (Cardinal) on Jul 22, 2021 at 15:38 UTC
    For some time, it was possible to use
    push $scalar, @values;

    It's not possible anymore. You have to dereference the scalar. In this particular case, use

    push @{ $TTTPLOT[$index] }, @twenty_SFs;

    BTW, this is not a valid syntax and has never been:

    push /@TTTPLOT, /@header;

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

      Thank you, after making your changes "Can't use string ("StartFerrite") as an ARRAY ref while "strict refs" in use at ../../plot_TTTDIA.pl line 58" this is a reference to temp_and_starts in the following block:

      # Read the file's per-temperature data while(<$in>) { # Split on multiple spaces using regex captured matches my @temp_and_starts = @{$_} =~ /[ +^\s]+/g; my @last_AT_fracs = <$in> =~ /[^\s +]+/g; my @twenty_SFs = (<$in> . <$in> . <$in> . <$in>) =~ /[^\s +]+/g; my $max_SF = max @twenty_SFs; # Build the @TTTPLOT row $TTTPLOT[$index]->[0] = $temp_and_starts[0]; $TTTPLOT[$index]->[1] = $temp_and_starts[1]; $TTTPLOT[$index]->[2] = $temp_and_starts[2]; $TTTPLOT[$index]->[3] = $temp_and_starts[3]; $TTTPLOT[$index]->[4] = $max_SF; push @{ $TTTPLOT[$index] }, @twenty_SFs; $index++; }

      Is this a simple fix or does it require an overhaul?

        Are you sure this has ever worked? This line makes no sense:
        my @temp_and_starts = @{$_} =~ /[^\s]+/g;

        Under warnings, it even warns:

        Applying pattern match (m//) to @array will act on scalar(@array)

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        Without knowing what the data looks like, here is my guess at what "should" work:
        my @temp_and_starts = $_=~/(\S+)/g; my @last_AT_fracs = scalar(<$in>) =~/(\S+)/g; my @twenty_SFs = (<$in> . <$in> . <$in> . <$in>) =~/(\S+) +/sg;

                        "The difficult we do today; the impossible takes a little longer."

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11135302]
Approved by davies
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-04-20 01:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found