Ссылка на строку как переменную класса - PullRequest
0 голосов
/ 11 июля 2011

Я пытаюсь сохранить ссылку на строку в переменной класса. Я хочу получить доступ к этой переменной, разыменовав ее. Например, в подпрограмме 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;

1 Ответ

3 голосов
/ 11 июля 2011

Когда вы вызываете ваш конструктор 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;
...