0

I am trying to add values to arrays in a hash.

foreach my $f (@files) {
  my $file = "$logDir/$f";
  open my $info, $file or die "Could not open $file: $!";
  while (my $line = <$info>) {
    chomp $line;
    if ($line =~ /CONN.*\[ID=(.*)\].*ID is(.*)/) {
      $b = $1;
      $a = $2;
      $a =~ s/^\s+//;
      $bHash{$b} = $a if (exists $aHash{$a});
    }
    elsif ($line =~ /succ.*\[ID=(.*)\].*/) {
      $b = $1;
      push(@{ $bHash{$b} }, "bSUCC") if (exists $bHash{$b});
    }
    elsif ($line =~ /fail.*\[ID=(.*)\].*/) {
      $b = $1;
      push(@{ $bHash{$b} }, "bFAIL") if (exists $bHash{$b});
    }
  }
  close $info;
}

I am linking two log files together based on a's transaction id and b's transaction id, which are both found on a single log line in b's log.

The first if statement checks for that, and populates %bHash with b->ID = a->Id.

Then I am looking for either success or fail of b's transaction. If I see a success line I take the transaction ID, and if that ID exists in %bHash then I want to push the "bSucc" message to the end of the array, i.e. %bHash would have bSid -> aSid, bSucc.

I get the following error/warning message:

Can't use string ("7747395") as an ARRAY ref while "strict refs" in use at ./report.pl line 54, <$info> line 833.

Is there a way to do this?

I also want to continue to add information to the array if possible as I scan the log for more data. I want to use the transaction ID as the key and just add info as necessary. Is this possible? Is there a better way to accomplish the task?

Edit: What I am trying to accomplish is to compile information about a transaction across 3 different log files. I want to find the following for each transaction: Success of Fail, If failed where did it fail, in log a, b, or c?

One transaction is handled by 3 different apps, hence 3 different logs. Unfortunately the trans id is different in app a vs apps b and c. So i built a hash with all the trans ids in log a, and then there is a log line in log b that allows you to see the link between the trans id used for log a and trans id used for log b. That is why I am matching trans id from b against the hash from log a. Ultimately I want the info for each transId as mentioned above, sucs/fail, etc.

3
  • This won't work at all, as you are initializing $bHash{$b} to the A Transaction ID, and then trying to push onto it as if it is an array reference. Please show theformat of your data files and describe exactly what it is that you need to do. It really looks like this belongs in a database. Commented Oct 13, 2013 at 22:30
  • Please learn to format your Perl properly, especially before asking question about it. Also, you must never use $a and $b as general-purpose variables, first of all because they aren't at all descriptive (the same reason you shouldn't call a hash %bHash) and secondly because they are used internally by Perl and you may get a clash of access. Commented Oct 13, 2013 at 22:31
  • added a bit of detail on my ultimate goal for storing the info. Commented Oct 13, 2013 at 22:41

1 Answer 1

3

The problem is that when you initially set each value in %bHash, you're setting it to a string value, not an arrayref:

      $bHash{$b} = $a if (exists $aHash{$a});

Later, you're trying to push a value onto "the array" by dereferencing it:

      push(@{ $bHash{$b} }, "bSUCC") if (exists $bHash{$b});

but since there is no array, just a string, Perl thinks you're trying to dereference the string into an array. (Which, I should note, is actually potentially legal — if $a is the string 'foo', then @$a means the global variable @foo — but that's not recommended, not allowed in the scope of use strict, and obviously not what you're trying to do. I mention it only because the text of the error-message thinks that that's the feature you're trying to use.)

The fix is simply to use an arrayref to begin with:

      $bHash{$b} = [$a] if (exists $aHash{$a});

so that you have an array you can safely push values onto.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! That worked perfectly and now I can add the id and the succ/fail to the array.

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.