Re^3: Help with script recognizing variable in string
by Laurent_R (Canon) on Jun 20, 2018 at 06:22 UTC
|
This works if the compiler can unambiguously recognize the end of the embedded variable name, for example if the variable name is followed by a space or a punctuation symbol.
If it is difficult to know where the variable name ends, you can use the following syntax: ${bfcomputer} to clarify.
| [reply] [d/l] |
|
|
Hi Laurent,
The return I get when using ${bfcomputer} yields all of the computers of the site not the computer supplied as the command line argument, but again for some reason when I use double quotes it works. Could this have something to do with using the system command on a Solaris box?
| [reply] |
|
|
I guess I wasn't clear enough. There are two distinct points.
One is that scalar variables are interpolated (i.e. the variable is replaced by its value, for example when printing out the string) within a string if the string is initialized within double quotes, but not if the string is initialized within simple quotes. So the change that you did from single quotes to double quotes was a good move (although there are some limitations, as mentioned below by other monks).
my $var = "foo";
print 'Variable name is $var'; # prints: Variable name is $var
print "Variable is $var"; # prints: Variable is foo
Then, even when the encompassing string is within double quotes, the compiler has to be able to know where the variable name ends to be able to interpolate the variable. It will be able to do so if the variable name is followed, for example, by a space or a punctuation symbol; but it might not be able to do it if the variable is followed by characters that are valid within an variable identifier, for example by some letters. In that case, a pair of curly brackets makes it possible to know where the variable name ends and the rest of the string starts, thereby removing any ambiguity. For example:
my $var = 10;
print "There are $varapples"; # error: the compiler cannot know wh
+ere the variable name ends
print "There are $var apples"; # OK: the space after the variable m
+akes it possible to know that the variable ends just there
print "There are ${var}apples"; # prints: there are 10apples.
# A space is missing, but the print
+statement works, because the compiler can know
# where the variable name ends thank
+s to the curlies;
I hope this is clearer. | [reply] [d/l] [select] |
|
|
c:\@Work\Perl\monks>perl -le
"use warnings;
use strict;
;;
my $var = 10;
my $hard_ref = \$var;
sub func { return $var; }
sub func_ref { return \ $var; }
;;
print
qq{arbitrary whitespace within the curlies: ${ var }apples \n},
qq{dereference of hard reference: ${ $hard_ref }apples \n},
qq{deref of ref to function return value: ${ \ func() }apples \n}
+,
qq{deref of function returning ref: ${ func_ref() }apples \n},
qq{deref of ref to expression result: ${ \(11 + func()) }apples \n}
+,
;
;;
no strict 'refs';
;;
our $name = 'road';
my $soft_ref = 'name';
;;
print
qq{dereference of symbolic reference: ${ $soft_ref }apples \n},
qq{quoted literal symbolic identifier: ${ 'name' }apples \n},
;
"
arbitrary whitespace within the curlies: 10apples
dereference of hard reference: 10apples
deref of ref to function return value: 10apples
deref of function returning ref: 10apples
deref of ref to expression result: 21apples
dereference of symbolic reference: roadapples
quoted literal symbolic identifier: roadapples
This looks to be mostly a bunch of examples of references, but I think of an expression like ${ symbol_name } as being a dereference of a literal symbol name, so there's a natural transition to a broader consideration of references. See perldata and perlref.
Some questions for consideration:
-
What happens if the no strict 'refs'; statement before the symbolic reference examples is removed?
-
If the package-global our $name ... ; variable is made a lexical (my) variable, e.g.,
my $name = 'road';
what happens?
-
Why are symbolic references Officially Frowned Upon? (hint)
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |
|
|
I stand corrected Laurent, when I tested putting the variable in curly braces I forgot to change the single quotes to double quotes so the curly braces with the double quotes works, thanks!
| [reply] |
Re^3: Help with script recognizing variable in string
by bliako (Abbot) on Jun 20, 2018 at 09:43 UTC
|
Hmmm, watch out double quotes could lead to problems if you had other variable-looking items, e.g. those prepended by a sigill ($,%,@,&,etc.) in your string and perl would want to interpolate them too! If they happen to exist, perl would be eager to replace them, if they do not exist perl will replace them with empty unless you used use strict; use warnings;
Why don't you build your $bfquery as a sequence of string concatenations using single quotes or variable contents, for example:
$bfquery=
# this is a string in single quotes so nothing is interpolated
'query?relevance=%28names%20of%20it%2C%20ip%20addresses%20of%20it
+%2C%20root%20server%20of%20it%2C%20operating%20systems%20of%20it%2C%2
+0
last%20report%20time%20of%20it%2C%20agent%20versions%20of%20it%2C%20va
+lues%20of%20results%20from%20%28BES%20Property%20%22_SupportGroup%22%
+29%20of%20it%29%20of%20bes%20
computers%20whose%20%28%20name%20of%20it%20as%20lowercase%20starts%20w
+ith%20%22'
# add to this the value of this perl variable
. $bfcomputer
# and also this fixed string
. '%22%29'
# end of concatenation
;
| [reply] [d/l] [select] |
|
|
$bfquery=
# this is a string in single quotes so nothing is interpolated
'query?relevance=%28names%20of%20it%2C%20ip%20addresses%20of%20it
+%2C%20root%20server%20of%20it%2C%20operating%20systems%20of%20it%2C%2
+0
+last%20report%20time%20of%20it%2C%20agent%20versions%20of%20it%2C%20v
+a
+lues%20of%20results%20from%20%28BES%20Property%20%22_SupportGroup%22%
+29%20of%20it%29%20of%20bes%20computers%20whose%20%28%20name%20of%20it
+%20as%20lowercase%20starts%20
+with%20%22'
# add to this the value of this perl variable
. $bfcomputer
# and also this fixed string
. '%22%29';
# end of concatenation
<?xml version="1.0" encoding="UTF-8"?>
<BESAPI xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNa
+mespaceSchemaLocation="BESAPI.xsd">
<Query Resource="(names of it, ip addresses of it">
<Result></Result>
<Error>This expression could not be parsed.</Error>
</Query>
</BESAPI>
sh: +%2C%20root%20server%20of%20it%2C%20operating%20systems%20of%20it%
+2C%20: not found
sh: +last%20report%20time%20of%20it%2C%20agent%20versions%20of%20it%2C
+%20va: not found
sh: +lues%20of%20results%20from%20%28BES%20Property%20%22_SupportGroup
+%22%: not found
sh: +29%20of%20it%29%20of%20bes%20computers%20whose%20%28%20name%20of%
+20it: not found
sh: +%20as%20lowercase%20starts%20: not found
sh: +with%20%22server01%22%29: not found
| [reply] [d/l] |
|
|
| [reply] [d/l] [select] |
Re^3: Help with script recognizing variable in string
by poj (Abbot) on Jun 20, 2018 at 15:40 UTC
|
use strict;
use URI::Escape;
my $values = join ', ',(
'names of it',
'ip addresses of it',
'root server of it',
'operating systems of it',
'last report time of it',
'agent versions of it',
'values of results from (BES Property "_SupportGroup") of it'
);
my $bfcomputer = 'ABC123';
my $who = 'name of it as lowercase starts with "'.$bfcomputer.'"';
my $relevance = "($values) of bes computers whose ( $who)";
my $bfquery = 'query?relevance='.uri_escape($relevance);
poj | [reply] [d/l] |
|
|
| [reply] |