print<<EOF in perl- To print $ - perl

Here I want to print the '$' sign. How to do that?
#!/perl/bin/perl
print <<EOF;
This sign $ is called dollar
It's a multiline
string
EOF
This is giving me result.
This sign is called dollar
It's a multiline
string
I want to print $.

Using EOF is equivalent to "EOF" - the here document is interpolated as if in double quotes. Backslash the dollar sign \$ or explicitly use single quotes to supress interpolation.
print << 'EOF';
...
EOF

Running your code with use warnings turned on gives me this:
Name "main::is" used only once: possible typo at foo.pl line 8.
Use of uninitialized value $is in concatenation (.) or string at foo.pl line 8.
This sign called dollar
It's a multiline
string
As you can see, the is is gone from the sentence, and so is the dollar sign. The warnings tell me why: a variable $is was found inside the string. Since it was empty, it was replaced by the empty string. Because you did not have warnings turned on, this was done quietly.
The moral is: Always use use warnings. Also beneficial in this case would have been use strict, as it would have caused the script to fail compilation due to an undeclared variable $is.
As for how to fix it, I believe choroba has the solution in his answer.

Related

Perl: quoting correctly all special characters [duplicate]

This question already has answers here:
How can I prevent Perl from interpreting double-backslash as single-backslash character?
(3 answers)
Closed 4 years ago.
I have this sample string, containing 2 backslashes. Please don't ask me for the source of the string, it is just a sample string.
my $string = "use Ppppp\\Ppppp;";
print $string;
Both, double quotes or quotes will print
use Ppppp\Ppppp;
Using
my $string = "\Quse Ppppp\\Ppppp;\E";
print $string;
will print
use\ Ppppp\\Ppppp\;
adding those extra backslashes to the output.
Is there a simple solution in perl to display the string "literally", without modifying the string like adding extra backslashes to escape?
I have this sample string, containing 2 backslashes. ...
my $string = "use Ppppp\\Ppppp;";
Sorry, but you're mistaken - that string only contains one backslash*, as \\ is a escape sequence in double-quoted (and single-quoted) strings that produces a single backslash. See also "Quote and Quote-like Operators" in perlop. If your string really does contain two backslashes, then you need to write "use Ppppp\\\\Ppppp;", or use a heredoc, as in:
chomp( my $string = <<'ENDSTR' );
use Ppppp\\Ppppp;
ENDSTR
If you want the string output as valid Perl source code (using its escaping), then you can use one of several options:
my $string = "use Ppppp\\Ppppp;";
# option 1
use Data::Dumper;
$Data::Dumper::Useqq=1;
$Data::Dumper::Terse=1;
print Dumper($string);
# option 2
use Data::Dump;
dd $string;
# option 3
use B;
print B::perlstring($string);
Each one of these will print "use Ppppp\\Ppppp;". (There are of course other modules available too. Personally I like Data::Dump. Data::Dumper is a core module.)
Using one of these modules is also the best way to verify what your $string variable really contains.
If that still doesn't fit your needs: A previous edit of your question said "How can I escape correctly all special characters including backslash?" - you'd have to specify a full list of which characters you consider special. You could do something like this, for example:
use 5.014; # for s///r
my $string = "use Ppppp\\Ppppp;";
print $string=~s/(?=[\\])/\\/gr;
That'll print $string with backslashes doubled, without modifying $string. You can also add more characters to the regex character class to add backslashes in front of those characters as well.
* Update: So I don't sound too pedantic here: of course the Perl source code contains two backslashes. But there is a difference between the literal source code and what the Perl string ends up containing, the same way that the string "Foo\nBar" contains a newline character instead of the two literal characters \ and n.
For the sake of completeness, as already discussed in the comments: \Q\E (aka quotemeta) is primarily meant for escaping any special characters that may be special to regular expressions (all ASCII characters not matching /[A-Za-z_0-9]/), which is why it is also escaping the spaces and semicolon.
Since you mention external files: If you are reading a line such as use Ppppp\\Ppppp; from an external file, then the Perl string will contain two backslashes, and if you print it, it will also show two backslashes. But if you wanted to represent that string as Perl source code, you have to write "use Ppppp\\\\Ppppp;" (or use one of the other methods from the question you linked to).

Not sure of the reason for output value

I have these two statements in a perl code that I'm trying to understand.
our $CSITOOLS=`/x/eng/csitools/netapp_menu/common/csitools.sh`;
print "${CSITOOLS}\n";
Output:
/x/eng/csitools
How does ${VARIABLE_NAME} work? (In this case {CSITOOLS})
Thanks!
From perldata:
As in some shells, you can enclose the variable name in braces
to disambiguate it from following alphanumerics (and underscores).
That is:
If you have a variable like $foo and you want to interpolate that whithin a string:
my $string = "This is $foobar";
then Perl would look for the variable $foobar. To make clear your variable's name
is just $foo you need to write
my $string = "This is ${foo}bar";
This is the way to delimit the variable's name. In your particular case the curlies {} aren't needed because "$CSITOOLS\n" already is unambiguous. However, it does no harm.
Perl allows you to surround the name of a scalar variable with braces ({}) to separate its name from any surrounding characters. Imagine you have the word "item" in a variable, and you want to print item99 within a string, with no whitespace in between:
my $name = "item";
print "${name}99\n";
Without the braces, perl would interpret the variable like this:
print "$name99\n";
...which is an undeclared, undefined variable, and definitely not what you mean. With warnings enabled, would display something like:
Use of uninitialized variable in ...
If warnings are not enabled, the program may merrily run along and do other things, possibly/likely breaking something far down the line. That makes things really difficult to troubleshoot.
In your simple case, the braces aren't needed, and you don't see them all that very often in print statements, unless you need to combine variables where there's no whitespace character between it and other valid variable characters when interpolating within a string.
From perldoc.perl.org
A string enclosed by backticks (grave accents) first undergoes double-quote interpolation. It is then interpreted as an external command, and the output of that command is the value of the backtick string, like in a shell.
Apparently, the result of csitools.sh is the string /x/eng/csitools

Cannot get correct return value in sprintf function call

My problem is that the return value im printing is not being translated into a value.
I have the following code in a test file.
#!/usr/bin/perl -I/srv/www/jonathan/m/www
my $var = sprintf("$%.1f lbs",(77*2.20462));
print $var;
Its returning: 0.1f instead of the value i need to see.
What am i doing incorrectly here? I'm a perl newbie.
Your problem is that Perl interprets "$%.1f" as the variable $% followed by ".1f". $% is a special Perl variable containing "The current page number of the currently selected output channel" (see perlvar) and that has the value 0, so what gets printed is the string "0.1f".
There are a few ways round this.
You can remove the dollar sign: sprintf("%.1f lbs",(77*2.20462)). But that changes the string that you display.
You can escape the dollar to tell Perl that it's not special: sprintf("\$%.1f lbs",(77*2.20462)).
But I think there's a better solution. Perl treats dollar signs as special characters in double-quoted strings. But there's no reason for your string to be double-quoted. So just change your format string to use single quotes: sprintf('$%.1f lbs',(77*2.20462)).
That last one is the solution I'd use.
Perl uses dolar($) symbol to declare a scalar variable, you need to remove the $ symbol from the sprintf.
corrected code
my $var = sprintf("%.1f lbs",(77*2.20462));
print $var;
output
169.8 lbs

In Perl, why does variable interpolation fail for a hexadecimal escape sequence?

In Perl, if I run the code:
print "Literal Hex: \x{50} \n";
I get this: "Literal Hex: P"
However, if I run the code:
my $hex_num = 50;
print "Interpolated Hex: \x{$hex_num}";
The variable does not interpolate properly and I get this: "Interpolated Hex:"
Similar failure results when I attempt to use variable interpolation in unicode and octal escape sequences.
Is it possible to use escape sequences (e.g. \x, \N) with interpolated string variables? I was under the impression that a $variable contained within double quotes is always interpolated, but is this the exception?
Note: Thanks to this question, I am aware of the workaround: chr(hex($hex_num)), but my above questions regarding variable interpolation for escape sequences still stand.
Interpolation is not recursive, everything is interpolated just once, from left to right. Therefore, when \x{$hex} is being processed, the following applies (cited from perlop):
If there are no valid digits between the braces, the generated character is the NULL
character ("\x{00}").
Zero is really there:
perl -MO=Deparse -e '$h=50;print "<\x{$h}>"'
$h = 50;
print "<\000>";
-e syntax OK
You should put in your variable the complete scape sequence:
my $hex_num = "\x50";
print "Interpolated Hex: $hex_num", "\n";
The issue I had was adding an escaped var into another variable such as:
$MYVAR = "20";
$myQuery = "\x02\x12\x10\x$MYVAR\x10";
Tried a number of \\x, \Q\x and various other escape sequences to no avail!!!
My workaround was not a direct escape but converting the var prior to adding to the string.
$MYVAR = chr(hex(20));
Did quite a bit of searching for a direct regex solution but had to run with this in the end.

Behavior of . and , operators in Perl for concatenation and parsing

I was trying to play with the . and , operators in Perl and got something weird which I was unable to figure out:
If I run this:
print hello . this,isatest, program
the output is:
hellothisisatestprogram
What I could understand is that it is treating both the text before and after the dot operator as string and concatenating them.
But what about the commas? Why is it getting omitted and not concatenated?
First period (.) is treated as concatenation operator. Subsequent commas separate multiple parameters of print. The result is the same - all parts are concatenated. If you want to print literal commas, enclose this,isatest, program in quotes - "this,isatest, program" to form single argument.
http://perldoc.perl.org/functions/print.html
I think this is what you want:
perl -e 'print "hello"." this,isatest,program"."\n"'
Run above code and check the output. If it gives you desired output then I guess we have an explanation.