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

so I have a text file, i would like to parse it so that it creates a new file with the 4 tab separated columns. here is the code i have so far. in addition how do i do regex to match a word from a column
!/usr/bin/perl use strict; use warnings; Pacakge CCD::Human; #declare new class my $in = ("/home/ki/Downloads/currenthumanccds.txt") or die "Can't ope +n file: $!"; #declare file in n path my $out = ("home/ki/output.txt") or die "Can't create file path: $!"; +#declare file out and path open (IN, $in) or die "$!"; open (OUT, '>' , $out) or die "$!"; my @text; my $input=<STDIN>; while (<IN>){ chomp; my @fields = ( split /\t/ ); } if ($in=~ /+\/),$text[6]){ print OUT "$text[2]\t $text[6]\t";# if a + is present print it and + the gene id text[2] }and{ if ($in=~ /withdrawn/),$text[5]{ print OUT "not public"; } }

Replies are listed 'Best First'.
Re: creating a class with encapsulation ?
by GrandFather (Saint) on Apr 26, 2016 at 03:30 UTC

    Clean up your code so it actually compiles with strictures.

    1. The first line is missing a # at the very start
    2. "Pacakge" is not spelt corectly and must be all lower case.
    3. my $in = ... and my $out = ... don't compile and don't make sense.
    4. if ($in =~ /+\/),$text[6]){ doesn't compile and doesn't make sense
    5. }and{ doesn't compile and doesn't make sense
    6. if ($in=~ / withdrawn /),$text[5]{ doesn't compile and doesn't make sense

    then provide some sample data and expected output. See I know what I mean. Why don't you?.

    Premature optimization is the root of all job security
Re: creating a class with encapsulation ?
by Athanasius (Archbishop) on Apr 26, 2016 at 04:02 UTC

    In addition to the excellent points made by GrandFather++, you should be aware that merely putting your code into a package does not make it a class. See perlootut.

    Another point: my @fields = ... declares a lexical variable with scope limited to the surrounding while loop. So, when the loop exits, the variable goes out of scope and its data are lost. Worse, the variable is re-defined on each iteration of the loop, so its previous contents are overridden. You need something along these lines:

    my @fields; while (<IN>) { chomp; push @fields, split /\t/; } # @fields is still in scope

    See push. And, of course, the variable @text is used without being declared.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      so i have my code down fine, it compiles. how do i convert it to a class ? any suggestions ? on how to create an object and methods ?
      #!/usr/bin/perl use strict; use warnings; my $in = ("/home/ki/Downloads/currenthumanccds.txt"); my $out = ("/home/ki/output.txt"); open (IN,"/home/ki/Downloads/CCDS.current.txt") or die "Cant open file +: $!"; open (OUT,">/home/ki/output.txt") or die "Cant open file: $!"; while(<IN>){ chomp; my@fields = (split/\t/); if ($fields[0] =~ m/16/ && $fields[6] eq"-" && $fields[5] =~ m/Pub +lic/){; print OUT "$fields[0] $fields[2] $fields[6] $fields[5 +]\n"; } }

        Here is the standard approach:

        (1) In file X/CCD/Human.pm (where X is some directory listed in @INC):

        package CCD::Human; use strict; use warnings; sub new { my ($class, $in_filename, $out_filename) = @_; my %self = ( in => $in_filename, out => $out_filename, ); return bless \%self, $class; } sub parse { my ($self) = @_; open(my $in, '<', $self->{in}) or die "Cannot open file '$self->{in}' for reading: $!"; open(my $out, '>', $self->{out}) or die "Cannot open file '$self->{out}' for writing: $!"; while (<$in>) { chomp; my @fields = split /\t/; print $out "$fields[0] $fields[2] $fields[6] $fields[ +5]\n" if ($fields[0] =~ /16/ && $fields[6] eq '-' && $fields[5] =~ /Public/); } close $in or die "Cannot close file '$self->{in}': $!"; close $out or die "Cannot close file '$self->{out}': $!"; }

        (2) Client code would use this class as follows:

        use CCD::Human; ... my $human = CCD::Human->new ( '/home/ki/Downloads/currenthumanccds.txt', '/home/ki/output.txt', ); ... $human->parse();

        Disclaimers:

        1. The above compiles but is otherwise untested.
        2. This doesn’t look like a use-case for which a class is either required or appropriate. Simply putting your code into a subroutine within a module would likely be a better approach.

        Hope that helps,

        Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,