Ссылка на строку как переменную класса

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

Когда вы звоните 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;
Другие вопросы по тегам