Re: Need help with s///
by ZZamboni (Curate) on Jul 14, 2000 at 22:24 UTC
|
The substitution is never happening, that's why. And there must
be something else you omitted, because as shown, your code
does not run because the $NETOBJ variable is not declared anywhere.
Removing the "use strict" makes it run, and running it with
the -w flag (always use -w and strict!) shows you the problem:
Name "main::NETOBJ" used only once: possible typo at t.pl line 6.
Use of uninitialized value in scalar dereference at t.pl line 6.
Use of uninitialized value in concatenation (.) at t.pl line 6.
Ok, here's what is happening:
- Because "$$NETOBJ.parameter" is in double quotes, Perl is
interpreting $NETOBJ as a variable, and trying to interpolate
its value. Because it doesn't have a value, you get an undef
value.
- Now, the first "$" in "$$NETOBJ" is also interpolated by
perl, trying to interpret it as a dereference to $NETOBJ (this
is, if $NETOBJ contained a reference to a scalar value, $$NETOBJ
would dereference it and give you the value). Because $NETOBJ
is undef, the dereferencing fails too, This produces the
"Use of uninitialized value in scalar dereference" error.
- At this point $a contains already ".parameter".
- The substitution is escaped correctly, therefore it looks for
the string '$$NETOBJ'. But that string is not there, therefore
the substitution doesn't happen, and you get ".parameter"
as your final result
The solution if you want the literal string '$$NETOBJ' in $a
is to use single quotes instead of double quotes. The single
quotes prevent interpolation. Like this:
$a='$$NETOBJ.parameter';
--ZZamboni
| [reply] [d/l] [select] |
|
|
Thanks to everyone for their helpful responses.
Actually, I was trying to keep my post brief, but I ended up leaving out too much information and still getting helpful information, but not the exact information I was seeking.
Ok, here's the story:
I'm parsing a config file and I'm running into a parameter that has a value like $$NETOBJ.parameter. I want to remove the $$NETOBJ. part and be left with parameter. The code I submitted earlier was a little test that I had put together, but I mistyped it. Here is my test program as I was using it:
#!/usr/local/bin/perl
$a = "$$NETOBJ.parameter";
$a =~ s/\$\$NETOBJ\.//;
print $a;
Earlier, I typed use strict; out of habit. I usually use it, but left it out for this small example.
What the code above gives me is .parameter. My question is: Why doesn't my regexp remove the dot? I don't need to know how to create the value because I'm already reading it from the config file. I need to know how to remove the dot.
Sorry again for not being more specific. Thank you all for your feedback.
Tii | [reply] [d/l] |
|
|
The regex doesn't remove the dot because the regex doesn't match. Let's make two small changes:
#!/usr/local/bin/perl -w
$a = "$$NETOBJ.parameter";
print ">>$a<<\n";
$a =~ s/\$\$NETOBJ\.//;
print $a;
You might also write it this way:
$a = "$$NETOBJ.parameter";
if ($a =~ s/\$\$NETOBJ\.//) {
print $a;
} else {
print "Substitution failed.\n";
}
One other approach that may work for you is split:
$a = '$$NETOBJ.parameter';
(undef, $a) = split(/\./, $a, 2);
print $a;
Of course, notice the single quotes in the declaration that time. That'll help even if you do use the regexp. | [reply] [d/l] [select] |
Re: Need help with s///
by mrmick (Curate) on Jul 14, 2000 at 22:20 UTC
|
Actually, I tried your example and got the following:
Global symbol "$NETOBJ" requires explicit package name at F:\reg.pl li
+ne 7.
Execution of F:\reg.pl aborted due to compilation errors.
It seems as though it was trying to interpolate the
variable in the double quoted string. Once I replaced the
"s with 's , the program ran and gave the following output:
parameter
Here's the change:
$a = '$$NETOBJ.parameter';
Mick | [reply] [d/l] [select] |
Re: Need help with s///
by c-era (Curate) on Jul 14, 2000 at 22:17 UTC
|
Your regex is fine, but you didn't escape the $$ initialy. This works for me.
use strict;
my $a;
$a = "\$\$NETOBJ.parameter";
$a =~ s/\$\$NETOBJ\.//;
print $a;
| [reply] [d/l] |
Re: Need help with s///
by Abigail (Deacon) on Jul 15, 2000 at 00:02 UTC
|
That's pretty amazing that your program pretty anything
at all, as I cannot get it to compile. Are you sure you
have the use strict; there? Because that should
tell you what you are doing wrong.
-- Abigail | [reply] |
Re: Need help with s///
by target (Beadle) on Jul 15, 2000 at 00:51 UTC
|
I LOVE PERL, so many different ways to get the same result.
The single quotes turn off the interpolation as ZZamboni and mrmick offered and so does escaping both of the $'s as c-era offered.
| [reply] |
RE: Need help with s///
by Adam (Vicar) on Jul 15, 2000 at 01:59 UTC
|
At this point you already have your answer, but I wanted to point out something that would have helped you find the answer faster: check your s/// call for success. $a =~ s/\Q$$NETOBJ.// or die "$a is not right";
UPDATE:
Abigail points out that the \Q won't prevent variable interpretation (damn) but that wasn't my point. My point was that you can only be sure a regex matched something if you check. To make Abigail happy I give you:$a =~ s/\$\$NETOBJ\.// or die "$a is not right";
| [reply] [d/l] [select] |
|
|
Actually, that would not have helped at all. The \Q will
turn off interpretation of regular expression meta characters,
but it will not prevent interpolation to
happen. Hence, with use strict; in effect, the thing
would still not compile, and without strict $$NETOBJ
would be the empty string (warnings were disabled - so you
don't get that error message), and the substitution would
successfully remove the dot. Hence, the die would
not happen.
-- Abigail
| [reply] |
|
|
I believe that "$!" would make the "or die" even better, by providing information on why the regex didn't check.
If so, that gives you:
$a =~ s/\$\$NETOBJ\.// or die "$a is not right: $!";
| [reply] [d/l] |
Re: Need help with s///
by Anonymous Monk on Jul 15, 2000 at 17:52 UTC
|
I have an even better idea. Why create a string with text, and then remove it? Just by default have the string as "parameter". | [reply] |
|
|
#!/usr/local/bin/perl
open (F, "textfile") or die "Could not open file: $!";
$a = <F>;
$a =~ s/\$\$NETOBJ\.//;
print $a;
This code outputs parameter. It turns out that the way I was simulating reading text from a file was part of my problem.
Thanks to everyone for the help.
Humbly,
Tii | [reply] [d/l] |