0

I'm trying to save a reference to a string in a class variable. I wish to access this variable by dereferencing it. For example in the routine getHeaders instead of using:

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

I would like to use:

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

For more details you should see the code at the end. My problem is, that the program doesn't work when I don't work with the copy( i.e when I don't use $fileContentsRef1). What am I doing / getting wrong? Is it possible to reach the goal in the way I described? Could some give me clues how?

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;
0

1 Answer 1

3

When you call your class->new(...) constructor with a filename argument, the new subroutine gets the class name as the first argument, and the filename as the second argument.

In your constructor, you are simply copying the value of $_[1] (the filename) into $self->{FileRef}, but that value is not a reference.

So when you access it, there is no need to use a doubled sigil to dereference the value.

You should run all of your code with the following two lines at the top, which will catch many errors for you (including trying to use strings as references when they are not references):

use strict;
use warnings;

These two lines basically move Perl out of quick one-liner mode, and into a mode more suitable for large development (improved type safety, static variable name checking, and others).


Per the update: If the code you have is working properly when copying the string, but not when dereferencing it directly, it sounds like you may be running into an issue of the string reference preserving the last match position (the g flag).

Try running the following:

my $fileContentsRef = $this->getFileContent;
pos($$fileContentsRef) = 0;  # reset the match position
$$fileContentsRef =~ /Spaltenname.*?Datentyp.*?---\n(.*?)\n\n/gsmi;
Sign up to request clarification or add additional context in comments.

2 Comments

hi Erik, thank you for a quick reply. I call it with reference to a string as argument (see the edited question).
one more question... how can i dereference $self->{fileRef} to be able to use pos() = 0 in the get method? thanks in advance

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.