s_gaurav1091 has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I am assigning a xml message to a variable.Now the problem is that when I am printing that message.The varible is not reflecting . I mean suppose I have assigned a message like $message = "<event id=\"ALERT_$tier_$code1\" source=\"APP\">"; Now when I am printing the $message ,its coming <event id="ALERT_0" source="APP". The $tier value is not coming.Why is this happening?I am attaching my code also with this. Plz somebody help
my $temp; my $code; my $info; my $count = 0; my $length = scalar@contents; for(my $i=0;$i<=$length;$i++) { chomp($contents[$i]); if($contents[$i] =~ /\w+=(\d+)/){ $code = $1; $code1 = $code; chomp($contents[$i+1]); $info = $contents[$i+1]; substr($info,0,5) = ""; $temp = substr($code ,0,1); #print "$temp --> code\n"; if($temp == 1) { $tier = "WEB"; } if($temp == 2) { $tier = "APP"; } if($temp == 3) { $tier = "DB"; } if($code1 != 0) { $severity = 1; } if($code1 = 0) { $severity = 5; } #print "$code1 --> $tier\n"; $message = "<event id=\"ALERT_$tier_$code1\" source=\" +APP\">"; print "$message --messgae\n"; } }

Replies are listed 'Best First'.
Re: the variable is not getting assigned
by GrandFather (Saint) on Jan 11, 2006 at 04:47 UTC

    Add use warnings; use strict; to the start of your code. After you have resolved the errors that that generates, and if you still have a problem, ask the question again with the modified code.

    My guess is that $tier and $code1 are going out of scope so when you get to the assignment new variables are created and have undefined values.

    Note that in addition to the scoping problem if($code1 = 0) should probably be if($code1 == 0). For purposes of testing a value for @contents would be nice. _$tier_$code has to be written _${tier}_$code or Perl will think the variable is %tier_.

    Updated to provide sample code


    DWIM is Perl's answer to Gödel
      Note that in addition to the scoping problem if($code1 = 0) should probably be if($code1 == 0).

      Curiously enough this node (in an interesting thread) about mistyping = for == in if clauses was cited a few hours before.

Re: the variable is not getting assigned
by ikegami (Patriarch) on Jan 11, 2006 at 05:39 UTC
    We know what code is "0", so that means that $temp is "0", so that means $tier is undef since it is never assigned a value. Undef stringifies to "", which is consitant with the results obtained. (You'll get a warning if warnings were used.) Maybe you need a default value for $tier?
Re: the variable is not getting assigned
by jbrugger (Parson) on Jan 11, 2006 at 06:57 UTC
    I know it's not a big issue, but personally i don't like to put variables captured in between quotes like this:
    my $message = "<event id=\"ALERT_$tier_$code1\" source=\"APP\">";
    I do think it's better maintainable, readable etc. if you concatenate strings like this:
    my $message = "<event id=\"ALERT_" . $tier . "_" . $code1 . "\" source=\"APP\">";
    As you immediately see in the last line, the $tier and $code1 are Perl variables, as you don't see that as fast in your given one.

    update: or indeed use grandfather's ${tier}

    update2: I have to agree to davidrw, sprintf works even more clean. I have to admit as well, that i don't use it that often, even though it's a great function for string formatting, and i really don't know why.
    Perhaps i need to force myself a bit more :).

    "We all agree on the necessity of compromise. We just can't agree on when it's necessary to compromise." - Larry Wall.

      IMHO both variations suffer from escapism.

      When I have to insert double quotes into a double quoted string, I will most likely use qq for better readability:

      my $message = qq(<event id="ALERT_${tier}_$code1" source="APP">);

      YMMV

      I often like using sprintf for it instead of variable concatentation .. note also using single quotes for the string literals means you don't have to have the escaping backslashes...
      my $message = sprintf '<event_id="ALTER_%d_%d" source="APP">', $tier, +$code1;

      Also, to OP: I second blazar's comments, and would also add to them that your assignment of $severity with the two if statements can simply be written as:
      $severity = $code1 ? 1 : 5;
      Though, what's the point of $severity ? It doesn't seem to be used...
Re: the variable is not getting assigned
by s_gaurav1091 (Beadle) on Jan 11, 2006 at 04:55 UTC
    Hi I should have tried inserting a backslash infrint of unederscore like this $message = "<event id=\"ALERT\_$tier\_$code1\" source=\" It working. Thanx anyways

      Even if you found a fix that seems to make it work, do not ignore the good advices GrandFather (and others) gave you. To add to them:

      my $temp; my $code; my $info; my $count = 0;

      Generally variables should be declared in the innermost lexical scope in which they're actually needed rather than all at the top.

      my $length = scalar@contents;

      no need for that explicit scalar. And as a matter of style, Perl is a free form language: try to adjust whitespace to improve readability. (Or to degrade it - but only if you're playing obfu!)

      for(my $i=0;$i<=$length;$i++) {

      As a general rule, there are situations in which C-style for loops are preferrable. But they're rare! more commonly it is recommendable to use Perl-style ones, and in particular in this case I don't see what the former buys you over the latter.

      if($temp == 1) { $tier = "WEB"; } if($temp == 2) { $tier = "APP"; } if($temp == 3) { $tier = "DB"; } if($code1 != 0) { $severity = 1; } if($code1 = 0) { $severity = 5; }

      These smell like you may save some complexity and use a hash instead. That would make the code more maintainable as well: you'd just have to add/remove/modify keys accordingly.