Subroutine name beginning with underscore in Perl - perl

Here's an example from the Markdown source:
sub _StripLinkDefinitions{ somecode }
What does it mean? Is it just a convention or a part of the language?

It is an convention, documented in the perlstyle:
You can use a leading underscore to indicate that a variable or
function should not be used outside the package that defined it.
Also, in the Perl best practices page 49, says:
Prefix “for internal use only” subroutines with an underscore.
with the explanation:
A utility subroutine exists only to simplify the implementation of a
module or class. It is never supposed to be exported from its module,
nor ever to be used in client code.
Always use an underscore as the
first “letter” of any utility subroutine’s name. A leading underscore
is ugly and unusual and reserved (by ancient C/Unix convention) for
non-public components of a system. The presence of a leading
underscore in a subroutine call makes it immediately obvious when part
of the implementation has been mistaken for part of the interface.
Related: The underscore has an special meaning too, as a part of a language - e.g.:
the variable what's name is only the underscore, (check perlvar) - e.g:
$_ - The default input and pattern-searching space.
#_ - list of all subroutine arguments
_ - The special file handle what caches the information from the last stator file test operator (such -f)
language constructions what starts and ends with a double underscore, such: __DATA__, __END__, __FILE__, __PACKAGE__, __LINE__

Related

Powershell function reference and naming conventions

I recently discovered that you can get powershell's functions by reference using the modifier $function:. But I noticed a strange problem...
By convention, POSH uses a {Verb}-{Noun} convention for function names, where {Verb} is part of aproved POSH verb names. For instance: Get-Member or Invoke-WebRequest.
The thing is, that calling $function:Get-Member, for example, is not valid because of the hyphen; it works just fine if you declare a function like ShowMessage and calls: $fn = $function:ShowMessage. So I'd like to know if there's a way to escape this call.
PS.: I do know of another option, but is much much more verbose:
function Show-Message { Write-Host "Foo"; }
$fn = (Get-Item "function:Show-Message").ScriptBlock;
$fn.Invoke();
Update: Although #PetSerAl was very helpfull and explained the problem, I'll mark #Ansgar Wiechers's response as the answer because it's better documented.
function: is a PSDrive, not a (scope)modifier. As for using it with variable-like notation ($function:name): the rules for variable names with special characters apply here as well.
From the documentation:
VARIABLE NAMES THAT INCLUDE SPECIAL CHARACTERS
Variable names begin with a dollar sign. They can include alphanumeric characters and special characters. The length of the variable name is limited only by available memory.
Whenever possible, variable names should include only alphanumeric characters and the underscore character (_).Variable names that include spaces and other special characters, are difficult to use and should be avoided.
To create or display a variable name that includes spaces or special characters, enclose the variable name in braces. This directs PowerShell to interpret the characters in the variable name literally.
Your notation should thus look like this:
${function:Show-Message}
It can be invoked like this:
& ${function:Show-Message}

What is the meaning of ${} in powershell?

I have a script where function parameters are expressed like this:
param(
${param1},
${param2},
${param3}
)
What does it mean? I have been unable to find documentation on this.
What's the point of writing parameters that way instead of the more usual
param(
$param1,
$param2,
$param3
)
?
#MikeZ's answer is quite correct in explaining the example in the question, but as far as addressing the question title, there is actually more to say! The ${} notation actually has two uses; the second one is a hidden gem of PowerShell:
That is, you can use this bracket notation to do file I/O operations if you provide a drive-qualified path, as defined in the MSDN page Provider Paths.
(The above image comes from the Complete Guide to PowerShell Punctuation, a one-page wallchart freely available for download, attached to my recent article at Simple-Talk.com.)
They are both just parameter declarations. The two snippets are equivalent. Either syntax can be used here, however the braced form allows characters that would not otherwise be legal in variable names. From the PowerShell 3.0 language specification:
There are two ways of writing a variable name: A braced variable name, which begins with $, followed by a curly bracket-delimited set of one or more almost-arbitrary characters; and an ordinary variable name, which also begins with $, followed by a set of one or more characters from a more restrictive set than a braced variable name allows. Every ordinary variable name can be expressed using a corresponding braced variable name.
From about_Variables
To create or display a variable name that includes spaces or special characters, enclose the variable name in braces. This directs Windows PowerShell to interpret the characters in the variable name literally.
For example, the following command creates and then displays a variable named "save-items".
C:\PS> ${save-items} = "a", "b", "c"
C:\PS> ${save-items}
a
b
c
They are equivalent. It's just an alternative way of declaring a variable.
If you have characters that are illegal in a normal variable, you'd use the braces (think of it as "escaping" the variablename).
There is one additional usage.
One may have variable names like var1, var2, var11, var12, var101, etc.
Regardless if this is desirable variable naming, it just may be.
Using brackets one can precisely determine what is to be used:
assignment of $var11 may be ambiguous, using ${var1}1 or ${var11} leaves no room for mistakes.

Perl subroutines - do they need to be called with parentheses? [duplicate]

This question already has answers here:
Why is parenthesis optional only after sub declaration?
(4 answers)
Closed 7 years ago.
I built a simple subroutine, and I have a question about whether calling it requires parentheses.
#!/usr/bin/perl
sub echo {
print "#_ \n" ;
}
echo(#ARGV);
When I use
echo #ARGV
or
echo (#ARGV)
or (without a space)
echo(#ARGV)
they all work. Which one is correct?
echo #ARGV, echo (#ARGV), and echo(#ARGV) are technically all correct in your case, but using parentheses is sometimes necessary; beyond that, it's a matter of choice, and some people employ conventions around when to use what style.
Enclosing the entire argument list in parentheses ALWAYS works - whether spaces precede the opening parenthesis or not - echo (#ARGV) or echo(#ARGV) - and whether you're calling a built-in or user-defined function (subroutine):
As #xxfelixxx notes in a comment on the question, perldoc perlstyle recommends no spaces between the function name and ( - echo(#ARGV).
Enclosing the entire argument list in parentheses can be used to disambiguate:
print (1 + 2) + 4 prints only 3, because (1 + 2) is interpreted as the entire argument list (with + 4 added to the the expression value of the print call, the result of which is not output).
print((1 + 2) + 4) resolves the ambiguity and prints 7.
Alternatively, prefix the parenthesized first argument with + to achieve the same effect: print +(1 + 2) + 4 also prints 7.
Not using parentheses - echo #ARGV - works:
with built-in functions: always
with user-defined functions: ONLY if they are predeclared, which can be ensured in one of the following ways:
The function is defined in the same script before its invocation.
The function is forward-declared with sub <name>; before its invocation.
The function is imported from a module with use before its invocation (require is not enough).
This predeclaration requirement is is an unfortunate side effect of backward compatibility with the earliest Perl versions - see this answer.
In the absence of a predeclaration, the safest approach is to use parentheses (while &echo #ARGV works in principle, it bypasses any prototypes (a form of parameter typing) that the function may declare).
As for conventions:
Since using parentheses always works (even when not strictly needed) with user-defined functions, whereas they are never needed for built-in functions, some people recommend always using parentheses with user-defined functions, and never with built-in functions.
In source code that adheres to this convention, looking at any function call then tells you whether a built-on or user-defined function is being invoked.
The parens are optional. You need them in some situations to explicitly show which values are the arguments to the function, for example, when passing the result of a function call to another function:
myfunc(1, 2, otherfunc(3), "z");
Without parens around the 3, otherfunc will receive both 3 and "z" as arguments.
As xxfelixxx mentioned, it's best to use them all the time.

Perl variables defined with * vs $

What's the difference between defining a variable with a * vs a $? For example:
local $var;
local *var;
The initial character is known as a sigil, and says what sort of value the identifier represents. You will know most of them. Here's a list
Dollar $ is a scalar value
At sign # is an array value
Percent % is a hash value
Ampersand & is a code value
Asterisk * is a typeglob
You are less likely to have come across the last two recently, because & hasn't been necessary when calling subroutines since Perl 5.0 was released. And typeglobs are a special type that contains all of the other types, and are much more rarely used.
I'm considering how much deeper to go into all of this, but will leave my answer as it is for now. I may write more depending on the comments that arise.
$var is a scalar. *var is a typeglob. http://perldoc.perl.org/perldata.html#Typeglobs-and-Filehandles
It's not a variable in the strictest sense. You shouldn't generally be using it.

Why does the Perl CGI module use hyphens to start named arguments?

I am a novice. My question is what is the "-" before the keys (type, expires name etc) standing for? Why not just use the plain hash table way and discard the hyphen?
# #!/usr/local/bin/perl -w
use CGI;
$q = CGI->new;
print $q->header(-type=>'image/gif',-expires=>'+3d');
$q->param(-name=>'veggie',-value=>'tomato');
The author already explained in the documentation.
Most CGI.pm routines accept several
arguments, sometimes as many as 20
optional ones! To simplify this
interface, all routines use a named
argument calling style that looks like
this:
print
$q->header(-type=>'image/gif',-expires=>'+3d');
Each argument name is preceded by a
dash. Neither case nor order matters
in the argument list. -type, -Type,
and -TYPE are all acceptable. In
fact, only the first argument needs to
begin with a dash. If a dash is
present in the first argument, CGI.pm
assumes dashes for the subsequent
ones.
Several routines are commonly called
with just one argument. In the case
of these routines you can provide the
single argument without an argument
name. header() happens to be one of
these routines. In this case, the
single argument is the document type.
print $q->header('text/html');
See perlop:
If the operand is an identifier, a string consisting of a minus sign concatenated with the identifier is returned. Otherwise, if the string starts with a plus or minus, a string starting with the opposite sign is returned. One effect of these rules is that -bareword is equivalent to the string "-bareword". (emphasis mine)
This is just an older style of perl arguments that isn't usually used in newer modules. It's not exactly deprecated, it's just an older style based on how Perl allows you to not quote your hash keys if they start with a dash.
I don't know what you mean by the 'plain hashtable way'. The way CGI::pm is implemented, names of properties are (in most cases) required to be preceded by '-', presumably so that they can be identified.
Or to put it another way, the hash-key required by CGI::header to identify the 'type' property is '-type'.
That's just the way CGI.pm is defined.