0

我正在尝试在类变量中保存对字符串的引用。我希望通过取消引用来访问这个变量。例如在例程中getHeaders而不是使用:

my $fileContentsRef = $this->getFileContent;
my $fileContentsRef1 =  $$fileContentsRef;
$fileContentsRef1 =~ /Spaltenname.*?Datentyp.*?---\n(.*?)\n\n/gsmi;

我想使用:

my $fileContentsRef = $this->getFileContent;
$$fileContentsRef =~ /Spaltenname.*?Datentyp.*?---\n(.*?)\n\n/gsmi;

有关更多详细信息,您应该在最后看到代码。我的问题是,当我不使用副本时(即当我不使用时),程序不起作用$fileContentsRef1。我在做什么/做错了什么?是否可以按照我描述的方式达到目标?有人能给我一些线索吗?

open FILE, "a1.bad"; 
$file_contents .= do { local $/; <FILE> }; 
close FILE; 
my $log = auswerter->new(\$file_contents); 


#-----------------------------------------------------------------
# Subs
#-----------------------------------------------------------------

# CONSTRUCTOR
sub new
{
    my $fileRef = $_[1];
    my $self = {};
    bless $self;
    $self->initialize();
    if($fileRef) { $self->{fileRef} = $fileRef; }
    return $self;
}
sub initialize
{
#-----------------------------------------------------------------
# Configuration
#-----------------------------------------------------------------
    my $this = shift;
}
sub setFile {
    my $this = shift;
    $this->{file} = shift;
}
sub getFileContent
{
  my $this = shift;
  return    $this->{fileRef};
}
sub getHeaders
{
  print "HEADERS...\n";

  my $this = shift;
  my @headers = ();
  my $fileContentsRef = $this->getFileContent;
  my $fileContentsRef1 =  $$fileContentsRef;

  $fileContentsRef1 =~ /Spaltenname.*?Datentyp.*?---\n(.*?)\n\n/gsmi;
  @headers = split ("\n", $1 ); 
  foreach (@headers)
  {
    $_ =~ s/^(.*?)\s.*/$1/;
  } 
  return \@headers;
}
sub getErrList
{
    print "ERR LIST...\n";
    my $this = shift;
    my @errors = ();
    my $fileContentsRef = $this->getFileContent;
    my $fileContentsRef1 =  $$fileContentsRef;

    $fileContentsRef1 =~ /Spaltenname.*?(Satz.*)ORA.*?^Tabelle/gsmi;
    return \@errors if !$1;

    @errors = split ("\n\n", $1 );
    foreach (@errors)
    {

           $_ =~ s/.*Spalte (.*?)\..*/$1/msgi;
    }
    return \@errors;
}
sub getEntries
{
  my $this = shift;
  my @entries = ();
  my $fileContentsRef = $this->getFileContent;
  my $fileContentsRef1 =  $$fileContentsRef;
  $fileContentsRef1 =~ /.*==\n(.*)/gsmi;
  @entries = split ("\n", $1 );
  return \@entries;
}
sub sqlldrAnalyze
{
    my $this = shift;
    my $token = shift;
    my $errRef =$this->getErrList();
    return "" if $#$errRef < 0 ;

    my $headersRef = $this->getHeaders();
    my $entriesRef = $this->getEntries();
    my $i = 0;
    my $str = "";
    $str = "<html>";
    $str .= "<table rules=\"all\">";
    $str .= "<tr>";
    foreach ( @$headersRef)
    {
      $str .= "<th>".$_."</th>";
    }
    $str .= "</tr>";    
    foreach ( @$entriesRef)
    {
      my @errOffset  = grep { $headersRef->[$_] =~ $errRef->[$i] }0..$#$headersRef  ;
      my @entries =  split($token, $_);
      $str .= "<tr>";
      foreach (my $j =0; $j <= $#entries;$j++)
      {
        $str .= "<td nowrap";
        $str .= " style=\"background-color: red\"" if $j  == $errOffset[0];;
        $str .= ">";
        $str .= "<b>" if $j  == $errOffset[0];
        $str .= $entries[$j];
        $str .= "</b>" if $j == $errOffset[0];
        $str .= "</td>";        
    }
    $str .= "</tr>\n";
    $i++;
  }
  $str .= "</table>";
  $str .= "</html>";
  return $str;
}
return 1;
4

1 回答 1

3

当您class->new(...)使用文件名参数调用构造函数时,new子例程将类名作为第一个参数,将文件名作为第二个参数。

在您的构造函数中,您只是将$_[1](文件名)的值复制到中$self->{FileRef},但该值不是引用。

因此,当您访问它时,无需使用双印记来取消引用该值。

您应该在顶部使用以下两行运行所有代码,这将为您捕获许多错误(包括在字符串不是引用时尝试使用字符串作为引用):

use strict;
use warnings;

这两行基本上使 Perl 脱离了快速单行模式,进入更适合大型开发的模式(改进的类型安全性、静态变量名检查等)。


根据更新:如果您拥有的代码在复制字符串时正常工作,但在直接取消引用时不能正常工作,听起来您可能会遇到字符串引用保留最后匹配位置(g标志)的问题。

尝试运行以下命令:

my $fileContentsRef = $this->getFileContent;
pos($$fileContentsRef) = 0;  # reset the match position
$$fileContentsRef =~ /Spaltenname.*?Datentyp.*?---\n(.*?)\n\n/gsmi;
于 2011-07-11T15:01:22.493 回答