Symbolic reference to sub in a package, trying to understand - perl

use strict;
use warnings;
package Foo::Bar;
sub baz { print "$_[0]\n" }
package main;
{ # test 1
my $quux = "Foo::Bar::baz";
no strict 'refs';
&$quux(1);
}
{ # test 2
my $qux = 'Foo::Bar';
my $quux = "$qux\::baz";
no strict 'refs';
&$quux(2);
}
{ # test 3
my $qux = 'Foo::Bar';
my $quux = "$qux::baz";
no strict 'refs';
&$quux(3);
}
Output:
Name "qux::baz" used only once: possible typo at test31.pl line 21.
1
2
Use of uninitialized value $qux::baz in string at test31.pl line 21.
Undefined subroutine &main:: called at test31.pl line 23.
Why does test 2 work, and why does backslash has to be placed exactly there?
Why does test 3 not work, is it so far, in syntax, from test 1?
I tried to write that string as "{$qux}::baz", but it doesn't work, too.
I came across this looking at source of Image::Info distribution.

$qux::baz refers to scalar baz in package qux.
"$qux::baz" is the stringification of that scalar.
"$qux::baz" is another way of writing $qux::baz."".
Curlies can be used to indicate where the variable ends.
"$foo bar" means $foo." bar"
"${f}oo bar" means $f."oo bar"
As such,
"${qux}::baz" is another way of writing $qux."::baz".
"$qux\::baz" is a cute way of doing $qux."::baz" since \ can't appear in variable names.

A variable name can either be simple like $foo or a fully qualified name (in the case of package variables). Such a fully qualified name looks like $Foo::bar. This is the “global” variable $bar in the package Foo.
If an interpolated variable is to be followed by a double colon :: and the variable should not be interpreted as a fully qualified package variable name, then you can either:
Use string concatenation: $qux . "::baz"
Terminate the variable name with a backslash: "$qux\::baz"
Surround the variable name (not the sigil) with curly braces, as if the name were a symbolic reference: "${qux}::bar".

Related

Perl ref() does not print the 'HASH' type

The following code does not print the 'HASH' type. What is wrong with this code ?
#! /usr/bin/perl
$prices{'pizza'} = 12.00;
$prices{'coke'} = 1.25;
$prices{'sandwich'} = 3.00;
print ref($prices);
First of all, you should put use strict; and use warnings; at the top of your script (and do that for all the future Perl code as well). After doing so, you will see the following:
Global symbol "%prices" requires explicit package name at ./a.pl line 4.
Global symbol "%prices" requires explicit package name at ./a.pl line 5.
Global symbol "%prices" requires explicit package name at ./a.pl line 6.
Global symbol "$prices" requires explicit package name at ./a.pl line 7.
Execution of ./a.pl aborted due to compilation errors.
What it means is that you tried to use to separate variables: a %prices hash and a $prices scalar.
After fixing variable declaration using my %prices;, you can get a reference to your %prices hash as follows:
my $prices_ref = \%prices;
print ref($prices_ref);
From formal standpoint, the answer may be shorter:
ref($prices) would return 1 if $prices value were a reference to another variable or false otherwise.
ref($prices) is the first use of an undeclared variable $prices (previous lines refer to another undeclared variable - hash %prices).
The value of $prices is undef and ref($prices) is an empty string.
Probably, your idea was to write
$prices->{'pizza'} = 12.00;
$prices->{'coke'} = 1.25;
$prices->{'sandwich'} = 3.00;
print ref($prices);

Can someone explain why Perl behaves this way (variable scoping)?

My test goes like this:
use strict;
use warnings;
func();
my $string = 'string';
func();
sub func {
print $string, "\n";
}
And the result is:
Use of uninitialized value $string in print at test.pl line 10.
string
Perl allows us to call a function before it has been defined. However when the function uses a variable declared only after the function call, the variable appears to be undefined. Is this behavior documented somewhere? Thank you!
The behaviour of my is documented in perlsub - it boils down to this - perl knows $string is in scope - because the my tells it so.
The my operator declares the listed variables to be lexically confined to the enclosing block, conditional (if/unless/elsif/else), loop (for/foreach/while/until/continue), subroutine, eval, or do/require/use'd file.
It means it's 'in scope' from the point at which it's first 'seen' until the closing bracket of the current 'block'. (Or in your example - the end of the code)
However - in your example my also assigns a value.
This scoping process happens at compile time - where perl checks where it's valid to use $string or not. (Thanks to strict). However - it can't know what the value was, because that might change during code execution. (and is non-trivial to analyze)
So if you do this it might be a little clearer what's going on:
#!/usr/bin/env perl
use strict;
use warnings;
my $string; #undefined
func();
$string = 'string';
func();
sub func {
print $string, "\n";
}
$string is in scope in both cases - because the my happened at compile time - before the subroutine has been called - but it doesn't have a value set beyond the default of undef prior to the first invocation.
Note this contrasts with:
#!/usr/bin/env perl
use strict;
use warnings;
sub func {
print $string, "\n";
}
my $string; #undefined
func();
$string = 'string';
func();
Which errors because when the sub is declared, $string isn't in scope.
First of all, I would consider this undefined behaviour since it skips executing my like my $x if $cond; does.
That said, the behaviour is currently consistent and predictable. And in this instance, it behaves exactly as expected if the optimization that warranted the undefined behaviour notice didn't exit.
At compile-time, my has the effect of declaring and allocating the variable[1]. Scalars are initialized to undef when created. Arrays and hashes are created empty.
my $string was encountered by the compiler, so the variable was created. But since you haven't executed the assignment yet, it still has its default value (undefined) during the first call to func.
This model allows variables to be captured by closures.
Example 1:
{
my $x = "abc";
sub foo { $x } # Named subs capture at compile-time.
}
say foo(); # abc, even though $x fell out of scope before foo was called.
Example 2:
sub make_closure {
my ($x) = #_;
return sub { $x }; # Anon subs capture at run-time.
}
my $foo = make_closure("foo");
my $bar = make_closure("bar");
say $foo->(); # foo
say $bar->(); # bar
The allocation is possibly deferred until the variable is actually used.

2 Sub references as arguments in perl

I have perl function I dont what does it do?
my what does min in perl?
#ARVG what does mean?
sub getArgs
{
my $argCnt=0;
my %argH;
for my $arg (#ARGV)
{
if ($arg =~ /^-/) # insert this entry and the next in the hash table
{
$argH{$ARGV[$argCnt]} = $ARGV[$argCnt+1];
}
$argCnt++;
}
return %argH;}
Code like that makes David sad...
Here's a reformatted version of the code doing the indentations correctly. That makes it so much easier to read. I can easily tell where my if and loops start and end:
sub getArgs {
my $argCnt = 0;
my %argH;
for my $arg ( #ARGV ) {
if ( $arg =~ /^-/ ) { # insert this entry and the next in the hash table
$argH{ $ARGV[$argCnt] } = $ARGV[$argCnt+1];
}
$argCnt++;
}
return %argH;
}
The #ARGV is what is passed to the program. It is an array of all the arguments passed. For example, I have a program foo.pl, and I call it like this:
foo.pl one two three four five
In this case, $ARGV is set to the list of values ("one", "two", "three", "four", "five"). The name comes from a similar variable found in the C programming language.
The author is attempting to parse these arguments. For example:
foo.pl -this that -the other
would result in:
$arg{"-this"} = "that";
$arg{"-the"} = "other";
I don't see min. Do you mean my?
This is a wee bit of a complex discussion which would normally involve package variables vs. lexically scoped variables, and how Perl stores variables. To make things easier, I'm going to give you a sort-of incorrect, but technically wrong answer: If you use the (strict) pragma, and you should, you have to declare your variables with my before they can be used. For example, here's a simple two line program that's wrong. Can you see the error?
$name = "Bob";
print "Hello $Name, how are you?\n";
Note that when I set $name to "Bob", $name is with a lowercase n. But, I used $Name (upper case N) in my print statement. As it stands, now. Perl will print out "Hello, how are you?" without a care that I've used the wrong variable name. If it's hard to spot an error like this in a two line program, imagine what it would be like in a 1000 line program.
By using strict and forcing me to declare variables with my, Perl can catch that error:
use strict;
use warnings; # Another Pragma that should always be used
my $name = "Bob";
print "Hello $Name, how are you doing\n";
Now, when I run the program, I get the following error:
Global symbol "$Name" requires explicit package name at (line # of print statement)
This means that $Name isn't defined, and Perl points to where that error is.
When you define variables like this, they are in scope with in the block where it's defined. A block could be the code contained in a set of curly braces or a while, if, or for statement. If you define a variable with my outside of these, it's defined to the end of the file.
Thus, by using my, the variables are only defined inside this subroutine. And, the $arg variable is only defined in the for loop.
One more thing:
The person who wrote this should have used the Getopt::Long module. There's a major bug in their code:
For example:
foo.pl -this that -one -two
In this case, my hash looks like this:
$args{'-this'} = "that";
$args{'-one'} = "-two";
$args{'-two'} = undef;
If I did this:
if ( defined $args{'-two'} ) {
...
}
I would not execute the if statement.
Also:
foo.pl -this=that -one -two
would also fail.
#ARGV is a special variable (refer to perldoc perlvar):
#ARGV
The array #ARGV contains the command-line arguments intended for the
script. $#ARGV is generally the number of arguments minus one, because
$ARGV[0] is the first argument, not the program's command name itself.
See $0 for the command name.
Perl documentation is also available from your command line:
perldoc -v #ARGV

Difference between a BLOCK and a function in terms of scoping in Perl

Guys I'm a little bit confused, I was playing with scoping in Perl, when i encountered this one:
#! usr/bin/perl
use warnings;
use strict;
sub nested {
our $x = "nested!";
}
print $x; # Error "Variable "$x" is not imported at nested line 10."
print our $x; # Doesn't print "nested!"
print our($x) # Doesn't print "nested!"
But when i do this:
{
our $x = "nested";
}
print our($x); # Prints "nested"
print our $x; # Prints "nested"
print $x; # Prints "nested"
So guys can you explain to me why those works and not?
To restate DVK's answer, our is just a handy aliasing tool. Every variable you use in these examples is actually named $main::x. Within any lexical scope you can use our to make an alias to that variable, with a shortened name, in that same scope; the variable doesn't reset or get removed outside, only the alias. This is unlike the my keyword which makes a new variable bound to that lexical scope.
To explain why the block example works the way it does, let's look at our explanation from "Modern Perl" book, chapter 5
Our Scope
Within given scope, declare an alias to a package variable with the our builtin.
The fully-qualified name is available everywhere, but the lexical alias is visible only within its scope.
This explains why the first two prints of your second example work (our is re-declared in print's scope), whereas the third one does not (as our only aliases $x to the package variable within the block's scope). Please note that printing $main::x will work correctly - it's only the alias that is scoped to the block, not the package variable itself.
As far as with the function:
print our $x; and print our($x) "don't work" - namely, correctly claim the value is uninitialized - since you never called the function which would initialize the variable. Observe the difference:
c:\>perl -e "use strict; use warnings; sub x { our $x = 1;} print our $x"
Use of uninitialized value $x in print at -e line 1.
c:\>perl -e "use strict; use warnings; sub x { our $x = 1;} x(); print our $x"
1
print $x; won't work for the same reason as with the block - our only scopes the alias to the block (i.e. in this case body of the sub) therefore you MUST either re-alias it in the main block's scope (as per print our $x example), OR use fully qualified package global outside the sub, in which case it will behave as expected:
c:\>perl -e "use strict; use warnings; sub x { our $x = 1;} print $main::x"
Use of uninitialized value $x in print at -e line 1.
c:\>perl -e "sub x { our $x = 1;} x(); print $main::x"
1

What does "1;" mean in Perl?

I have come across a few Perl modules that for example look similar to the following code:
package MyPackage;
use strict;
use warnings;
use constant PERL510 => ( $] >= 5.0100 );
require Exporter;
our #ISA = qw(Exporter);
our #EXPORT = qw( );
{ #What is the significance of this curly brace?
my $somevar;
sub Somesub {
#Some code here
}
}
1;
What is the significance of 1; and of the curly braces that enclose the $somevar and the Sub?
1 at the end of a module means that the module returns true to use/require statements. It can be used to tell if module initialization is successful. Otherwise, use/require will fail.
$somevar is a variable which is accessable only inside the block. It is used to simulate "static" variables. Starting from Perl 5.10 you can use keyword state keyword to have the same results:
## Starting from Perl 5.10 you can specify "static" variables directly.
sub Somesub {
state $somevar;
}
When you load a module "Foo" with use Foo or require(), perl executes the Foo.pm file like an ordinary script. It expects it to return a true value if the module was loaded correctly. The 1; does that. It could be 2; or "hey there"; just as well.
The block around the declaration of $somevar and the function Somesub limits the scope of the variable. That way, it is only accessible from Somesub and doesn't get cleared on each invocation of Somesub (which would be the case if it was declared inside the function body). This idiom has been superseded in recent versions of perl (5.10 and up) which have the state keyword.
Modules have to return a true value. 1 is a true value.
Perl modules must return something that evaluates to true. If they don't, Perl reports an error.
C:\temp>cat MyTest.pm
package MyTest;
use strict;
sub test { print "test\n"; }
#1; # commented out to show error
C:\temp>perl -e "use MyTest"
MyTest.pm did not return a true value at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
C:\temp>
Although it's customary to use "1;", anything that evaluates to true will work.
C:\temp>cat MyTest.pm
package MyTest;
use strict;
sub test { print "test\n"; }
"false";
C:\temp>perl -e "use MyTest"
C:\temp> (no error here)
For obvious reasons another popular return value is 42.
There's a list of cool return values maintained at http://returnvalues.useperl.at/values.html.
The curly braces limit the scope of the local variable $somevar:
{
my $somevar;
...
} # $somevar's scope ends here
From the documentation for require:
The file must return true as the last
statement to indicate successful
execution of any initialization code,
so it's customary to end such a file
with 1; unless you're sure it'll
return true otherwise. But it's better
just to put the 1; , in case you add
more statements.
I don't know much about Perl, but usually you create a scope using curly braces. Probably $somevar shoudln't be available globally?