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

I have written a perl code for filtering data contained in a file ($input_file_name) based on the filter expression($expr). While doing this, I face some problems. When I hard code the arrays @data and @col in the code, I am getting the results. But the moment I get the arrays @col and @data based on the user input file ($input_file_name) inside the "if" loop, there is no filter. The reason is @data array inside the "if" loop, when accessed outside has only one value and that doesn't satisfy the filter expression. Then I changed it as $array$i. Now I don't know how should I modify
  1. the sub routine sub filterdata
  2. my @result array
  3. print join function
Can some one please suggest me what changes I have to do, so that I can get the results? Any help in this regard is solicited.
#! /usr/bin/perl -w use strict; #- matter of style use warnings; #- and again my (@col,@data,$input_file_name,@temp,$header,$data_line,$i); $input_file_name= "MC_data.dat"; if (-s $input_file_name ) { open(INPUT, $input_file_name) || die "Cannot open: \nReason: $!\n" +; @temp = <INPUT> ; chomp @temp; $header = shift(@temp); $header =~ s/^\s+(.*)/$1/; #Remove the leading white s +paces @col = split /\s+/, $header; foreach $i ( 0 .. $#temp ) { $data_line = $temp[$i]; $data_line =~ s/^\s+(.*)/$1/; #Remove the leading white spaces @data = split /\s+/, $data_line; $data[$i] = split /\s+/, $data_line; } } @col = qw (RUN a1 a2 a3 weight sig1 sig2 sig3); @data=( [qw( 1 0.200000 0.200000 0.200000 0.765685 75881.9 29289.3 -46592.6)], [qw( 2 0.200345 0.200000 0.200345 0.966661 75766.0 29268.4 -46497.6)], [qw( 3 0.200000 0.200345 0.200000 0.766030 75867.1 29259.8 -46607.4)], [qw( 4 0.359575 0.253987 0.359575 1.271019 43898.7 19675.6 -24223.1)], [qw( 5 0.359921 0.253987 0.359921 1.271995 43861.3 19666.1 -24195.2)] ); map{ my $i=$_; no strict 'refs'; *{"filter::$col[$i]"} = sub{$_->[$i]} + } 0..$#col; sub filterdata { my $cref=shift; grep &$cref,@_ } sub filterspec { my $e = shift; map{ $e =~ s/\b$_\b/filter::$_()/g } @col; eval "sub{ $e }" } my $expr = "weight < 1.2 && sig1 > 75800"; my $filter_handler = filterspec( $expr ) or die $@; my @result = filterdata ($filter_handler,@data); print join("$/",map{join(" ",@$_)}@result).$/;

Edit: Added <code> tags, minor formatting. larsen

Replies are listed 'Best First'.
Re: Array accessing
by matija (Priest) on Mar 04, 2004 at 14:21 UTC
    AAAAAGGGHHHH! Please, please, please enclose code you post in <code> </code>> - otherwise it is very, very hard to read.

    And use preview so that you can see when your post is unreadable.

    Now, if I see correctly, inside your foreach loop, you're doing:

    foreach $i ( 0 .. $#temp ) { $data_line = $temp[$i]; $data_line =~ s/^\s+(.*)/$1/; #Remove the leading white spaces @data = split /\s+/, $data_line; $data[$i] = split /\s+/, $data_line; }
    Look at the last two lines of the loop. First you set all the elements of @data to the parts of $data_line, and then you overwrite one of them (whichever one $i is pointing to) with the number of the fields in $data_line. (That's what split returns when you call it in scalar context).

    Could that be the source of your problems?