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

Dear Monks,

I have tried to adapt some code that somebody has kindly given me. The problem I have is related to my attempt to print the year to file within the map function. The code shows where I have tried this without success. This question relates to my previous post .
#! perl -slw use strict; my @files; my $file; while (<*.txt>) { next if $_ eq 'out.txt'; # next if $1 < 1990; $file = $_; push (@files, $_); } my $out = "out.txt"; open (OUT, "+>$out"); my $file_in_question; my $year; foreach (@files){ #print "Age\tMale\tFemale"; $file_in_question = $_; if ($file_in_question =~ /^(\d{4})/){ $year = $1; } open (FILE, "$file_in_question"); # print OUT "$year\t"; # This does not work print OUT for map{ ## And strip out the combined total. # print OUT "$year\t"; # This does not work s[(^\d+\s+)[\d\.]+\s+][$1]; $_; } sort { ## Sort the lines by age local $^W; ## Ignoring non-numeric warnings $a <=> $b } grep{ ## Remove any lines that don't fit the pattern m[^\d+\s] } map{ ## Split lines that fit the two column pattern into two m[(^\d+\s+(?:[\d\.]+\s+){3})(.+$)] } <FILE>; }

Replies are listed 'Best First'.
Re: map function - print to file problem
by fishbot_v2 (Chaplain) on Oct 19, 2005 at 11:18 UTC

    Somewhat unrelated to your question, but this if needs an else. You use $year later, and don't otherwise reset it:

    if ($file_in_question =~ /^(\d{4})/){ $year = $1; }

    As for your actual question, does this work?

    print OUT for map{ s[(^\d+\s+)[\d\.]+\s+][$1]; "$year\t$_"; } sort { # ... etc.

    addendum: I would follow BrowserUk's advice in Re^3: Regex problem and replace the map pipeline with a series of steps. You aren't comfortable with this code the way it is.

      Your answer for the 'actual question' works. Thankyou for that. To address your first point I have done the following:
      if ($file_in_question =~ /^(\d{4})/){ $year = $1; } else { next; }
      Also I would like to say that BrowerUK's explanation offered in the post you refer to, I believe, is very well written. I would encourage anyone here to read it through.
Re: map function - print to file problem
by blazar (Canon) on Oct 19, 2005 at 12:29 UTC
    Your description is misleading, since you're not trying to print "within the map function". OTOH your code still has many quirks which many people has been repeatedly warning you about, including but not limited to unchecked opens and useless pieces of code. Refusal to correct these bad habits is a symptom of your nonwillingness to follow the advices you're asking for...

    Now, the way you chain the first map with grep suggests me that you have a poor understanding, if any, of the code you're working on. If this were for a one-time only dirty and uninformed hack, we could accept it. But since it seems you want to stick with perl, a basic understanding of it would be welcome. Intentionally avoiding it is irrespectful either.

    All in all it's (next to) imnpossible to really understand from both your code and the description of your prolem what the latter is.

      I was just thinking that I must return to those Perl books that I read years ago. I used to have some understanding of the map function. I have to admit that I no longer have it. I take your point on board.
Re: map function - print to file problem
by Delusional (Beadle) on Oct 19, 2005 at 10:57 UTC
    I might just be reading this wrong, however, you opened a file with the handle FILE open (FILE, "$file_in_question");, (but you didn't catch for problems: open (FILE, "$file_in_question") || die "Oops";) so unless I'm just totally missunderstanding the code, you would want to print to FILE not OUT, i.e. print FILE "$year\t";.

    But then again, I may be totally wrong...
      I want to print to the output file and not the input file. The years do print to the file but not in the positions that I want them to. What I want is: Year\tAge\tNumber_of_males\tNumber_of_females. And this form needs to print on multiple lines. Sorry I should have mentioned that earlier.