my %order;
while ( my $rec = $data->fetchrow_hashref ) {
push #{ $result{ $rec->{"ID"} } }, $rec->{"item"};
push #order, $rec->{ID};
}
I get Global symbol "#order" requires explicit package name at linepush #order, $rec->{ID};
Perl's sigils identify distinct data types. And two identical identifiers are different variables entirely if they have different sigils.
my $var; # This is a scalar.
my #var; # This is an array.
my %var; # This is a hash.
Each of those three are completely different variables.
The error message you are getting is because in line one of the code you posted you declare a hash named %order, while on line four of the code you posted, you push to an array named #order. That array has never been declared. Without an explicit declaration indicating otherwise, Perl will assume the first time it sees a variable that it's intended to be a package global. And because you're using strict 'vars', or strict (where vars is implicit`), Perl doesn't let you autovivify a package global, or any other type of variable, without first declaring it unless you fully qualify its name.
This behavior is explained in perldoc strict, where it states:
This generates a compile-time error if you access a variable that was
neither explicitly declared (using any of my, our, state, or use vars
) nor fully qualified.
Since the clear intent in your code is to push values onto an array, it's probable that the simplest fix is to change your first line from my %order; to my #order;, so that you're declaring an array rather than a hash.
It's unclear, without seeing more code, to know what to do with the line where you're pushing onto an array by reference, though. Presumably you already know that part of the code to be correct.
You declare the hash %order, but try to use the array #order.
Related
Final Edit: I'm making one last edit to this question for clarity sake. I believe it has been answered in all of the comments, but in the event there is such an option, I think it's best to clean up the question for future readers.
I recently inherited someone's Perl code and there's an interesting setup and I'm wondering if it can be made more efficient.
The program is setup to use strict and warnings (as it should). The program is setup to use global variables; meaning the variables are declared and initialized to undef at the top of the program. Specific values beyond the initial undef are then assigned to the variables throughout various loops within the program. After they are set, there is a separate report section (after all internal loops and subroutines have run) that uses the variables for its content.
There are quite a few variables and it seems repetitive to just make an initial variable declaration at the top of the program so that it is available later for output/report purposes (and to stay compliant with the strict pragma). Based on my understanding and from all of the comments received thus far, it seems this is the only way to do it, as lexically scoped variables by definition only persist in during their declared scope. So, in order to make it global it needs to be declared early (i.e. at the top).
I'm just wondering if there is a shortcut to elevate the scope of a variable to be global regardless of where it's declared, and still stay within strict's parameters of course?
My previous example was confusing, so I'll write a pseudo code example here to convey the concept (I don't have the original source with me):
# Initial declaration to create "Global variables" -- imagine about 30 or so
my ($var1, $var2, $var3); # Global
# Imagine a foreach loop going through a hash and assigning values
# to previously declared variables
for my $k (keys %h){
...
$var = 1; #$var gets set to 1 within the foreach loop
...
}
print "The final calculated report is as follows:\n";
#output $var after loop is done later in program
print "Variable 1 comes to $var1\n";
So the question: is there an acceptable shortcut that declares $var1 within the foreach loop above and escalates its scope beyond the foreach loop, so it is in effect "Global"? This would avoid the need to declare and initialize it to undef at the top of the program and still make it available for use in the program's output.
Based on feedback already received the answer seems to be an emphatic "No" due to the defined scoping constraints.
As per your own question:
So the question: is there an acceptable shortcut that declares $var1 within the foreach loop above and escalates its scope beyond the foreach loop, so it is in effect "Global"? This would avoid the need to declare and initialize it to undef at the top of the program and still make it available for use in the program's output.
You can refer to a variable name without having declared it first by using the whole name including namespace:
use strict;
use warnings;
my %h = (
first => 'value 1',
second => 'value 2',
third => 'value 3',
);
for my $k (keys %h) {
print "Processing key $k...\n";
$main::var = 1;
}
print "Variable var is now $main::var\n";
I'm assuming main as your namespace, which is the default. If your script is declaring a package, then you need to use that name. Also, if you didn't declare the variable first, you will need to use the whole package::name format everytime.
However, and just so it's clear: You don't need to "declare and initialize a variable to undef". If you do this:
my ($var1, $var2, $var3);
Those variables are already initialized to undef.
Now, you also need to understand the difference between a lexical and a global variable. Using the keyword my to declare variable at the top of your script will make them available in all the rest of your script, no matter if you are inside or outside a block. But they are not really global as they are not visible to any external module or script. If you change the keyword my to our, then they are global and visible anywhere outside that script.
I'm just wondering if there is a shortcut to elevate the scope of a variable to be global regardless of where it's declared, and still stay within strict's parameters of course?
Using global variables is dumb, but possible.
use vars qw( $foo );
It still needs to be present before any uses.
I've following two statements written in perl :
#m1 = ( [1,2,3],[4,5,6],[7,8,9] ); # It is an array of references.
$mr = [ [1,2,3],[4,5,6],[7,8,9] ]; # It is an anonymous array. $mr holds reference.
When I try to print:
print "$m1[0][1]\n"; # this statement outputs: 2; that is expected.
print "$mr->[0][1]\n"; #this statement outputs: 2; that is expected.
print "$mr[0][1]\n"; #this statement doesn't output anything.
I feel second and third print statements are same. However, I didn't any output with third print statement.
Can anyone let me know what is wrong with third print statement?
This is simple. $mr is a reference. So you use the Arrow Operator to dereference.
Also, if you would use use warnings; use strict;, you would have received a somewhat obvious error message:
Global symbol "#mr" requires explicit package name
$mr is a scalar variable whose value is a reference to a list. It is not a list, and it can't be used as if it was a list. The arrow is needed to access the list it refers to.
But hold on, $m1[0] is also not a list, but a reference to one. You may be wondering why you don't have to write an arrow between the indexes, like $m1[0]->[1]. There's a special rule that says you can omit the arrow when accessing list or hash elements in a list or hash of references, so you can write $mr->[0][1] instead of $mr->[0]->[1] and $m1[0][1] instead of $m1[0]->[1].
$mr holds a reference (conceptually similar to the address of a variable in compiled languages). thus you have an extra level of indirection. replace $mrwith $$mr and you'll be fine.
btw, you can easily check questions like these by browsing for tutorials on perldoc.
You said:
print "$m1[0][1]\n"; # this statement outputs: 2; that is expected.
print "$mr[0][1]\n"; #this statement doesn't output anything.
Notice how you used the same syntax both times.
As you've established by this first line, this syntax accesses the array named: #m1 and #mr. You have no variable named #mr, so you get undef for $mr[0][1].
Maybe you don't realizes that scalar $mr and array #mr have no relation to each other.
Please use use strict; use warnings; to avoid these and many other errors.
This is a code lifted straight from Perl Cookbook:
#colors = qw(red blue green yellow orange purple violet);
for my $name (#colors) {
no strict 'refs';
*$name = sub { "<FONT COLOR='$name'>#_</FONT>" };
}
It's intention is to form 6 different subroutines with names of different colors. In the explanation part, the book reads:
These functions all seem independent, but the real code was in fact only compiled once. This technique
saves on both compile time and memory use. To create a proper closure, any variables in the anonymous
subroutine must be lexicals. That's the reason for the my on the loop iteration variable.
What is meant by proper closure, and what will happen if the my is omitted? Plus how come a typeglob is working with a lexical variable, even though typeglobs cannot be defined for lexical variables and should throw error?
As others have mentioned the cookbook is using the term "proper" to refer to the fact that a subroutine is created that carries with it a variable that is from a higher lexical scope and that this variable can no longer be reached by any other means. I use the over simplified mnemonic "Access to the $color variable is 'closed'" to remember this part of closures.
The statement "typeglobs cannot be defined for lexical variables" misunderstands a few key points about typeglobs. It is somewhat true it you read it as "you cannot use 'my' to create a typeglob". Consider the following:
my *red = sub { 'this is red' };
This will die with "syntax error near "my *red" because its trying to define a typeglob using the "my" keyword.
However, the code from your example is not trying to do this. It is defining a typeglob which is global unless overridden. It is using the value of a lexical variable to define the name of the typeglob.
Incidentally a typeglob can be lexically local. Consider the following:
my $color = 'red';
# create sub with the name "main::$color". Specifically "main:red"
*$color = sub { $color };
# preserve the sub we just created by storing a hard reference to it.
my $global_sub = \&$color;
{
# create a lexically local sub with the name "main::$color".
# this overrides "main::red" until this block ends
local *$color = sub { "local $color" };
# use our local version via a symbolic reference.
# perl uses the value of the variable to find a
# subroutine by name ("red") and executes it
print &$color(), "\n";
# use the global version in this scope via hard reference.
# perl executes the value of the variable which is a CODE
# reference.
print &$global_sub(), "\n";
# at the end of this block "main::red" goes back to being what
# it was before we overrode it.
}
# use the global version by symbolic reference
print &$color(), "\n";
This is legal and the output will be
local red
red
red
Under warnings this will complain "Subroutine main::red redefined"
I believe that "proper closure" just means actually a closure. If $name is not a lexical, all the subs will refer to the same variable (whose value will have been reset to whatever value it had before the for loop, if any).
*$name is using the value of $name as the reference for the funny kind of dereferencing a * sigil does. Since $name is a string, it is a symbolic reference (hence the no strict 'refs').
From perlfaq7:
What's a closure?
Closures are documented in perlref.
Closure is a computer science term with a precise but hard-to-explain
meaning. Usually, closures are implemented in Perl as anonymous
subroutines with lasting references to lexical variables outside their
own scopes. These lexicals magically refer to the variables that were
around when the subroutine was defined (deep binding).
Closures are most often used in programming languages where you can
have the return value of a function be itself a function, as you can
in Perl. Note that some languages provide anonymous functions but are
not capable of providing proper closures: the Python language, for
example. For more information on closures, check out any textbook on
functional programming. Scheme is a language that not only supports
but encourages closures.
The answer carries on to answer the question in some considerable detail.
The Perl FAQs are a great resource. But it's a bit of a waste of effort maintaining them if no-one ever reads them.
Edit (to better answer the later questions in your post):
1/ What is meant by proper closure? - see above
2/ What will happen if the my is omitted? - It won't work. Try it and see what happens.
3/ How come a typeglob is working with a lexical variable? - The variable $name is only being used to define the name of the typeglob to work with. It's not actually being used as a typeglob.
Does that help more?
I'm no expert at Perl, wondering why the first way of obtaining numSheets is okay, while the following way isn't:
use Spreadsheet::Read;
my $spreadsheet = ReadData("blah.xls");
my $n1 = $spreadsheet->[1]{sheets}; # okay
my %sh = %spreadsheet->[1]; # bad
my $n2 = $sh{label};
The next to last line gives the error
Global symbol "%spreadsheet" requires explicit package name at newexcel_display.pl line xxx
I'm pretty sure I have the right sigils; if I experiment I can only get different errors. I know spreadsheet is a reference to an array not directly an array. I don't know about the hash for the metadata or individual sheets, but experimenting with different assumptions leads nowhere (at least with my modest perl skill.)
My reference on Spreadsheet::Read workings is http://search.cpan.org/perldoc?Spreadsheet::Read If there are good examples somewhere online that show how to properly use Spreadsheet, I'd like to know where they are.
It's not okay because it's not valid Perl syntax. The why is because that's not how Larry defined his language.
The sigils in front of variables tell you what you are trying to do, not what sort of variable it is. A $ means single item, as in $scalar but also single element accesses to aggregates such as $array[0] and $hash{$key}. Don't use the sigils to coerce types. Perl 5 doesn't do that.
In your case, $spreadsheet is an array reference. The %spreadsheet variable, which is a named hash, is a completely separate variable unrelated to all other variables with the same identifier. $foo, #foo, and %foo come from different namespaces. Since you haven't declared a %spreadsheet, strict throws the error that you see.
It looks like you want to get a hash reference from $spreadsheet->[1]. All references are scalars, so you want to assign to a scalar:
my $hash_ref = $spreadsheet->[1];
Once you have the hash reference in the scalar, you dereference it to get its values:
my $n2 = $hash_ref->{sheets};
This is the stuff we cover in the first part of Intermediate Perl.
In perl 5.8.5, if I do the following, I don't get an error:
use strict;
my $a = undef;
foreach my $el (#$a) {
...whatever
}
What's going on here? Printing out the output of ref($a) shows that $a changes to become a valid array reference at some point. But I never explicitly set $a to anything.
Seems kind of odd that the contents of a variable could change without me doing anything.
Thoughts, anyone?
EDIT: Yes, I know all about auto-vivification. I always thought that there had to be a assignment somewhere along the way to trigger it, not just a reference.
Auto-vivification is the word. From the link:
Autovivification is a distinguishing feature of the Perl programming
language involving the dynamic
creation of data structures.
Autovivification is the automatic
creation of a variable reference when
an undefined value is dereferenced. In
other words, Perl autovivification
allows a programmer to refer to a
structured variable, and arbitrary
sub-elements of that structured
variable, without expressly declaring
the existence of the variable and its
complete structure beforehand.
In
contrast, other programming languages
either: 1) require a programmer to
expressly declare an entire variable
structure before using or referring to
any part of it; or 2) require a
programmer to declare a part of a
variable structure before referring to
any part of it; or 3) create an
assignment to a part of a variable
before referring, assigning to or
composing an expression that refers to
any part of it.
Perl autovivication can be contrasted against languages such as Python, PHP, Ruby, JavaScript and all the C style languages.
Auto-vivification can be disabled with no autovivification;
Read Uri Guttman's article on autovivification.
There is nothing odd about it once you know about it and saves a lot of awkwardness.
Perl first evaluates a dereference expression and sees that the current reference value is undefined. It notes the type of dereference (scalar, array or hash) and allocates an anonymous reference of that type. Perl then stores that new reference value where the undefined value was stored. Then the dereference operation in progress is continued. If you do a nested dereference expression, then each level from top to bottom can cause its own autovivication.