Perl Subroutine Declaration Unexpected Symbols [duplicate] - perl

This question already has answers here:
What do dollar, at-sign and semicolon characters in Perl parameter lists mean?
(2 answers)
Closed 5 years ago.
I have been looking at some Perl code that has some subroutine declarations that make no sense to me. They appear as:
foo($$$$;$);
foo(\$\$\$);
What do the symbols ";" and "\" do or mean in these declarations?

They're "prototypes" - but Perl prototypes aren't like those in other languages, and probably shouldn't be used.
The $ denotes a scalar argument to the function. ;$ denotes an optional additional scalar argument. And \$ denotes a reference argument.
See also: Why are Perl 5's function prototypes bad?

Related

Perl: Bareword found where operator expected at [duplicate]

This question already has answers here:
Why is the escape of quotes lost in this regex substitution?
(2 answers)
Closed 4 years ago.
I am trying to use perl to replace a string like so:
perl -pe "s/FlDigVal/$DIGN/" Header.xml > $DDIRP/$FNAME.xml
If DIGN=+q4T/h/B8Saf0im3LtBevNvMPsd1PRG5Tz+Iq/uwjXA= i get the following syntax error:
Having no space between pattern and following word is deprecated at -e line 1.
Bareword found where operator expected at -e line 1, near "s/FlDigVal/+q4T/h"
Having no space between pattern and following word is deprecated at -e line 1.
syntax error at -e line 1, near "s/FlDigVal/+q4T/h"
Execution of -e aborted due to compilation errors.
I guess this is related to /hbeing in variable DIGN. Is there a way to escape those reserved words?
Don't use shell variables, which are just non-hygienic macros. Export the variable to Perl's environment:
DIGN=$DIGN perl -pe 's/FlDigVal/$ENV{DIGN}/'
Note the single quotes: we don't want the shell to change the Perl commands.
or pass the value as an argument:
perl -pe 'BEGIN { $replace = shift } s/FlDigVal/$replace/' "$DIGN" Header.xml
Nevertheless, you seem to be editing an XML document with regular expressions. It's a painful way, there are libraries like XML::LibXML that handle XML correctly. E.g. what would happen if DIGN contained & or <?
The problem is not with reserved words but /.
If DIGN contains +q4T/h/B8Saf0im3LtBevNvMPsd1PRG5Tz+Iq/uwjXA=, your command passes the following code to perl:
s/FlDigVal/+q4T/h/B8Saf0im3LtBevNvMPsd1PRG5Tz+Iq/uwjXA=/
Here s/FlDigVal/+q4T/ parses as a substitution command, but the rest is garbage.
The solution is to not let the shell interpolate variables into code. Instead you can pass strings via the environment:
DIGN="$DIGN" perl -pe 's/FlDigVal/$ENV{DIGN}/' Header.xml
(If DIGN is already exported, you don't need the DIGN="$DIGN" part.)
Here we use single quotes (no shell interpolation) and let perl grab a value from the environment.

What does this line do in Perl? [duplicate]

This question already has answers here:
How to Replace white space in perl
(3 answers)
Closed 5 years ago.
What does this line do in Perl?
s/\s//g;
I'm looking at a script that is used to search and count certain characters in an input file and I understand everything in the code except for this line. I was wondering what this line did for the script?
s/\s//g;
is short for
$_ =~ s/\s//g;
It is a substitution operator bound to $_. It replaces all sequences in $_ that match the regex pattern \s with nothing. (Without g, it would only replace the first.)
\s matches a character of whitespace.

What does ${1+"$#"} mean in a unix shell script? [duplicate]

This question already has answers here:
${1:+"$#"} in /bin/sh
(4 answers)
Closed 7 years ago.
I came across this construct while reviewing some older unix shell scripts, what does it mean, and why is is used?
${1+"$#"}
I found this explanation from unix haters handbook, page 152 of text (page 190 of the pdf). http://web.mit.edu/~simsong/www/ugh.pdf
It’s the way to exactly reproduce the command line arguments in the
/bin/sh family of shells shell script.
It says, “If there is at least one argument ( ${1+ ), then substitute in
all the arguments ( “$#” ) preserving all the spaces, etc. within each
argument.
If we used only “$#” then that would substitute to “” (a null argument)
if there were no invocation arguments, but we want no arguments reproduced in
that case, not “”.
Why not “$*” etc.? From a sh(1) man page:
Inside a pair of double quote marks (“”), parameter and
command substitution occurs and the shell quotes the results to
avoid blank interpretation and file name generation. If $* is
within a pair of double quotes, the positional parameters are
substituted and quoted, separated by quoted spaces (“$1
$2 …”); however, if $# is within a pair of double quotes, the
positional parameters are substituted and quoted, separated by
unquoted spaces (“$1” “$2” …).
I think ${1+“$#”} is portable all the way back to “Version 7 Unix.”
Wow! All the way back to Version 7.
Google should be your best friend! This is a similar questions asked almost 2 years ago.
https://unix.stackexchange.com/questions/68484/what-does-1-mean-in-a-shell-script-and-how-does-it-differ-from

What's the meaning of plain string when using as condition? [duplicate]

This question already has answers here:
How do I use boolean variables in Perl?
(9 answers)
Closed 8 years ago.
Below perl one-liner outputs hello to console, so how is false interpreted here since it is not a variable or literal string?
perl -e"if (false) {print 'hello'}"
In Perl false is true. The only terms that are evaluated as false are:
0, '0', '', (), (''), undef
FALSE/TRUE are not boolean values. They are called barewords and with use strict;, it will not even run.
From http://perldoc.perl.org/perldata.html
Barewords
A word that has no other interpretation in the grammar will be treated
as if it were a quoted string. These are known as "barewords".

Simultaneous "lower than" and "higher than" in Perl? [duplicate]

This question already has answers here:
Perl equivalent of (Postgre)SQL BETWEEN operator?
(5 answers)
Closed 8 years ago.
Is there a way to say
perl -e "#array=(1..10); foreach (#array){print qq{$_\n} if ($_>3 and $_<6);}"
more simply like
perl -e "#array=(1..10); foreach (#array){print qq{$_\n} if (3<$_<6);}"
(notice the differences inside the if statement).
Edit: running Perl v5.16.3
Not that I'm aware of. Consider you are looking for a ternary operator, which is quite rare in most programming languages. Usually unary and binary operators will suffice for most needs.
The only example I can think of a ternary operator is the conditional operator (cond ? true_statement : false_statement), used as a short-hand for the if-else clause for short statements.