重用在调用脚本时创建的对象

时间:2013-02-22 22:52:48

标签: perl object file-io

我希望将某些文本行从文件拆分为对象,并将这些对象添加到数组中,每个元素都是输入文件中的一行。从那里我需要调用此脚本的脚本能够通过其键引用对象中的标记(而不是将所有内容传递给print命令并在调用脚本中重新组装。

我的第一部分正在运行和测试,但我不清楚如何在调用脚本中发送或推送。我尝试打印出数组的每个元素,但因为它们是对象,所以在调用程序中,它们无法解除引用。

以下是创建数组的文件的简化版本:

#!/usr/bin/perl

use strict;
use warnings;
use CLASS::DATATYPE;

my $foundheaders = 0;
my $array_elem = 0;
my @MY_ARRAY = ();

open FH, '<', "dummy.txt";
# open FH, '<', "$ARGV[0]";

while (my $line = <FH>) {
    # once you've found the headers, this will begin to kickoff
    if ($foundheaders == 1)
    {
        # get line elements and create a new DATATYPE object using the elements
        # matched to the header index
        my @lineArray = split("\t", $line);
        my $thisdata = new CLASS::DATATYPE();

        $thisdata->FIRSTVAL(@lineArray[$HEADERS::FIRST]);
        $thisdata->SECONDVAL(@lineArray[$HEADERS::SECOND]);

        print "$thisdata\n";

        # Add new DATATYPE to the array
        $MY_ARRAY[$array_elem] = $thisdata;
        $array_elem ++;
    };

    # Search for line with "#R" at the beginning.  This will contain the headers
    if ($line =~ m/#R/ ) {
        # strip the first # symbol from the headers
        my $subline = substr $line, 1;
        chomp($subline);

        # split the line into an array and index headers
        my @headers = split("\t", $subline);
        &assign_headers(\@headers);

        # check off foundheaders flag
        $foundheaders = 1;
    };
};
close FH;

# test output value
my $test = $MY_ARRAY[2]->SECONDVAL();
print "$test\n";

1;

sub assign_headers
{
    package HEADERS;
    my @array = @{$_[0]};
    my $iter = 0;

    # check each array loop against known headers and assign the array index to header
    foreach (@array)
    {
        if ($_ eq "ROW1")
        {
            our $FIRST = $iter;
        };

        if ($_ eq "ROW2")
        {
            our $SECOND = $iter;
        };
        $iter++;
    }
}

可以将print语句固定在那里以确保至少按预期创建数据。

以下是存储在CLASS文件夹中的DATATYPE包:

#!/usr/bin/perl

package CLASS::DATATYPE;

use strict;
use warnings;

sub new {
    my $self = {};
    $self->{FIRSTVAL} = undef;
    $self->{SECONDVAL} = undef;
    $self->{THIRDVAL} = undef;
    bless($self);
    return $self;
}

sub FIRSTVAL {
    my $self = shift;
    if (@_) { $self->{FIRSTVAL} = shift }
    return $self->{FIRSTVAL};
}

sub SECONDVAL {
    my $self = shift;
    if (@_) { $self->{SECONDVAL} = shift }
    return $self->{SECONDVAL};
}

1;

我使用了一个任意的虚拟文件,任何带有匹配标题行的东西都可以工作:

## blah blah blah
## blah blah blah
#ROWS   ROW1    ROW2    ROW3
1   fwewef  aewf    sfd8y9
2   gereer  few79   dfsui
3   svfsg789    aferw789    uifdgs
4   dfsgy   78fer   fds
5   78fgds  sdf78y  sfdgh

调用文件类似于以下内容,传递输入文件并输出输出:

#!/usr/bin/perl

use strict;
use warnings;
use CLASS::DATATYPE;

my $file = "dummy.txt";

our @RESULTS = `/usr/bin/perl my_reader.pl $file`;

my $test = $RESULTS[2]->SECONDVAL();
print "$test\n";

1 个答案:

答案 0 :(得分:1)

我能想到解释我的意思的唯一方法就是为你编写程序。

这个程序正是你所需要的,我希望你能看到你写了不必要的大量代码来做同样的事情。

我已按照您的选择使用了该类,但您编写的所有内容都是实现Perl哈希的类。

请遵守我使用过的标识符的大小写。任何熟悉Perl的人都会习惯他们并且会感谢你。

我所做的唯一重要补充是List::MoreUtils模块用于firstidx功能。它返回符合给定测试的列表的第一个元素的索引。它不是核心模块,可能需要安装。如果确实无法安装新模块,那么在程序中编写等效函数是一件简单的事情。如果你需要帮助,请回来。

注意我已更新代码以删除对此模块的依赖,以防万一。

我已经让类从构造函数参数中获取初始化器,因此您可以在创建每个对象时分配值。此外,访问器在任何更改之前返回值,因为更改后的值不是很有用。

我希望你能看到现在所需要的只是处理其他文件格式的第二个子例程read_maf,而且不需要多个进程。

#!/usr/bin/perl

use strict;
use warnings;

use Class::DataType;

sub firstidx {
  my ($match, $list) = @_;
  for my $i (0 .. $#$list) {
    return $i if $list->[$i] eq $match;
  }
}

sub read_vcf {

  my ($filename) = @_;

  open my $fh, '<', $filename or die qq{Unable to open "$filename" for input: $!};

  my @columns;
  my @data;

  while (my $line = <$fh>) {
    chomp $line;
    if ( @columns ) {
        my @fields = split /\t/, $line;
        my $thisdata = Class::DataType->new(@fields[@columns]);
        push @data, $thisdata;
    }
    elsif ( $line =~ s/^#(?=R)// ) {
      my @headers = split /\t/, $line;
      @columns = map firstidx($_, \@headers), qw/ ROW1 ROW2 /;
    }
  }

  return \@data;
}

my $filename = 'dummy.txt';
my $results = read_vcf($filename);

my $test = $results->[2]->secondval;
print "$test\n";

Class::DataType

Class/DataType.pm的代码
package Class::DataType;

use strict;
use warnings;

sub new {
  my $package = shift;
  $package = ref $package if ref $package;
  my $self = {};
  @$self{qw/ firstval secondval thirdval /} = @_;
  bless $self, $package;
}

sub firstval {
    my $self = shift;
    my $retval = $self->{firstval};
    $self->{firstval} = shift if @_;
    return $retval;
}

sub secondval {
    my $self = shift;
    my $retval = $self->{secondval};
    $self->{firstval} = shift if @_;
    return $retval;
}

sub thirdval {
    my $self = shift;
    my $retval = $self->{thirdval};
    $self->{firstval} = shift if @_;
    return $retval;
}

1;

<强>输出

根据您提供的数据,打印

svfsg789