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.
Related
Below is code in which I need help.
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my #arrayElements = ('Array Functions');
print join(", ", #arrayElements);
### Output => Array Functions
my %hashElements = ();
I want to assign the content of #arrayElements to $hashElements{Item}
Missing some core concepts or trying wrong and been a while struggling with this.
You seem to be missing some core concepts of Perl (or programming in general). If you are learning Perl through a book or online tutorial, I suggest you re-read the chapters on arrays and hashes.
Let's look at the things involved here. You have:
#arrayElements, which is an array. It contains a list with one elements, the string 'Array Functions'.
%hashElements, which is a hash. It's empty.
$hashElements{Item}, which is a scalar value. You want to set this.
You say you want $hashElements{Item} to have the value 'Array Functions', which you have as the first element in your array #arrayElements.
$hashElements{Item} = $arrayElements[0];
And that's it. Both $hashElements{Item} and $arrayElements[0] are scalar values. That's why their sigils (the sign at the front) changes from an # (for array) or % (for hash) to a $. You can distinguish whether the value came from a hash or an array by the brackets used to access the elements. [] is for arrays, and {} is for hashes.
You cannot do the following though.
$hashElements{Item} = #arrayElements;
Because $hashElements{Item} is a scalar, the thing on the right hand side of the assignment will be treated in scalar context. An array in scalar context gets converted to the number of elements in the array, so this would assign 1. That's not what you want.
You should really read up more about this, and also pick better names for your variables. Your example is very confusing. In general, we don't do $CamelCase for variable names in Perl, but instead use $snake_case, which is easier to read and type.
Take a look at the following resources to learn more about the concepts I've mentioned above.
Perl Maven, perldata, perldsc
I am just wondering what does the curly bracket in between the string "name" means in Perl as per the example below? This is my first question, please be gentle and i am pretty new with perl
my $pool_name = $result->get->pool_attr("name")->{"name"};
To answer the question specifically, what are the curly braces. I would say here they're the syntax for a hash reference.
There's not much to explain on such a small snippet, but think of this:
%hash = (
'name' => "Harsha",
'designation' => "Manager"
);
$hash_ref = \%hash;
When we need to reference the particular element, we can use -> operator.
my $name = $hash_ref->{name};
This is a slightly modified example taken from - http://www.thegeekstuff.com/2010/06/perl-hash-reference/
Perl is a little terse this way. There are two concepts to understand here :-
Perl Object Access
Perl Reference Access
Just like java, we can have references in perl. Think of them as pointers in C if you are from C background. Now, if we want to access anything using the references, we use the "->" symbol. There are more concepts to this like blessing etc.But we won't go into that. But one important thing is that Perl Objects are also like HASH. And hence , all access to the perl Object members etc. are done in a similar fashion to HASH (HASH references , not hash objects).
So, we have an object $result.
$result->get calls the Get method on the Object. This method returns another object to you. Let's call it temp.
Now , on this object again, we call a member function pool_attr with a functional argument "name". This function returns the HASH to you finally.
Remember that Perl HASHes behave similarly to the perl Objects, so we access the "name" key using similar notation.
You can use print Data::Dumper::Dumper function and it will tell you more about the data structure. However note that perl Objects are kind of a hack so you might see a lot of unnecessary clutter with Data::Dumper::Dumper.
$pool_name is where the result will be stored.
$result is the variable holding the object.
->get is an action for the object $result.
->pool_attr("name") gets the value for the hashed item for the ->get action.
->{"name"} accesses the anonymous hash value associated with the name "name" for the value ->pool_attr("name")
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.
as a newbie I am trying to explore perl data structures using this material from atlanta perl mongers, avaliable here Perl Data Structures
Here is the sample code that I've writen, 01.pl is the same as 02.pl but 01.pl contains additional two pragmas: use strict; use warnings;.
#!/usr/bin/perl
my %name = (name=>"Linus", forename=>"Torvalds");
my #system = qw(Linux FreeBSD Solaris NetBSD);
sub passStructure{
my ($arg1,$arg2)=#_;
if (ref($arg1) eq "HASH"){
&printHash($arg1);
}
elsif (ref($arg1) eq "ARRAY"){
&printArray($arg1);
}
if (ref($arg2) eq "HASH"){
&printHash($arg2);
}
elsif (ref($arg2) eq "ARRAY"){
&printArray($arg2);
}
}
sub printArray{
my $aref = $_[0];
print "#{$aref}\n";
print "#{$aref}->[0]\n";
print "$$aref[0]\n";
print "$aref->[0]\n";
}
sub printHash{
my $href = $_[0];
print "%{$href}\n";
print "%{$href}->{'name'}\n";
print "$$href{'name'}\n";
print "$href->{'name'}\n";
}
&passStructure(\#system,\%name);
There are several points mentioned in above document that I misunderstood:
1st
Page 44 mentions that those two syntax constructions: "$$href{'name'}" and "$$aref[0]" shouldn't never ever been used for accessing values. Why ? Seems in my code they are working fine (see bellow), moreover perl is complaining about using #{$aref}->[0] as deprecated, so which one is correct ?
2nd
Page 45 mentions that without "use strict" and using "$href{'SomeKey'}" when "$href->{'SomeKey'}" should be used, the %href is created implictly. So if I understand it well, both following scripts should print "Exists"
[pista#HP-PC temp]$ perl -ale 'my %ref=(SomeKey=>'SomeVal'); print $ref{'SomeKey'}; print "Exists\n" if exists $ref{'SomeKey'};'
SomeVal
Exists
[pista#HP-PC temp]$ perl -ale ' print $ref{'SomeKey'}; print "Exists\n" if exists $ref{'SomeKey'};'
but second wont, why ?
Output of two beginning mentioned scripts:
[pista#HP-PC temp]$ perl 01.pl
Using an array as a reference is deprecated at 01.pl line 32.
Linux FreeBSD Solaris NetBSD
Linux
Linux
Linux
%{HASH(0x1c33ec0)}
%{HASH(0x1c33ec0)}->{'name'}
Linus
Linus
[pista#HP-PC temp]$ perl 02.pl
Using an array as a reference is deprecated at 02.pl line 32.
Linux FreeBSD Solaris NetBSD
Linux
Linux
Linux
%{HASH(0x774e60)}
%{HASH(0x774e60)}->{'name'}
Linus
Linus
Many people think $$aref[0] is ugly and $aref->[0] not ugly. Others disagree; there is nothing wrong with the former form.
#{$aref}->[0], on the other hand, is a mistake that happens to work but is deprecated and may not continue to.
You may want to read http://perlmonks.org/?node=References+quick+reference
A package variable %href is created simply by mentioning such a hash without use strict "vars" in effect, for instance by leaving the -> out of $href->{'SomeKey'}. That doesn't mean that particular key is created.
Update: looking at the Perl Best Practices reference (a book that inspired much more slavish adoption and less actual thought than the author intended), it is recommending the -> form specifically to avoid the possibility of leaving off a sigil, leading to the problem mentioned on p45.
Perl has normal datatypes, and references to data types. It is important that you are aware of the differerence between them, both in their meaning, and in their syntax.
Type |Normal Access | Reference Access | Debatable Reference Access
=======+==============+==================+===========================
Scalar | $scalar | $$scalar_ref |
Array | $array[0] | $arrayref->[0] | $$arrayref[0]
Hash | $hash{key} | $hashref->{key} | $$hashref{key}
Code | code() | $coderef->() | &$coderef()
The reason why accessing hashrefs or arrayrefs with the $$foo[0] syntax can be considered bad is that (1) the double sigil looks confusingly like a scalar ref access, and (2) this syntax hides the fact that references are used. The dereferencing arrow -> is clear in its intent. I covered the reason why using the & sigil is bad in this answer.
The #{$aref}->[0] is extremely wrong, because you are dereferencing a reference to an array (which cannot, by definition, be a reference itself), and then dereferencing the first element of that array with the arrow. See the above table for the right syntax.
Interpolating hashes into strings seldom makes sense. The stringification of a hash denotes the number of filled and available buckets, and so can tell you about the load. This isn't useful in most cases. Also, not treating the % character as special in strings allows you to use printf…
Another interesting thing about Perl data structures is to know when a new entry in a hash or array is created. In general, accessing a value does not create a slot in that hash or array, except when you are using the value as reference.
my %foo;
$foo{bar}; # access, nothing happens
say "created at access" if exists $foo{bar};
$foo{bar}[0]; # usage as arrayref
say "created at ref usage" if exists $foo{bar};
Output: created at ref usage.
Actually, the arrayref spings into place, because you can use undef values as references in certain cases. This arrayref then populates the slot in the hash.
Without use strict 'refs', the variable (but not a slot in that variable) springs into place, because global variables are just entries in a hash that represents the namespace. $foo{bar} is the same as $main::foo{bar} is the same as $main::{foo}{bar}.
The major advantage of the $arg->[0] form over the $$arg[0] form, is that it's much clearer with the first type as to what is going on... $arg is an ARRAYREF and you're accessing the 0th element of the array it refers to.
At first reading, the second form could be interpreted as ${$arg}[0] (dereferencing an ARRAYREF) or ${$arg[0]} (dereferencing whatever the first element of #arg is.
Naturally, only one interpretation is correct, but we all have those days (or nights) where we're looking at code and we can't quite remember what order operators and other syntactic devices work in. Also, the confusion would compound if there were additional levels of dereferencing.
Defensive programmers will tend to err towards efforts to make their intentions explicit and I would argue that $arg->[0] is a much more explicit representation of the intention of that code.
As to the automatic creation of hashes... it's only the hash that would be created (so that the Perl interpreter and check to see if the key exists). The key itself is not created (naturally... you wouldn't want to create a key that you're checking for... but you may need to create the bucket that would hold that key, if the bucket doesn't exist. The process is called autovivification and you can read more about it here.
I believe you should be accessing the array as: #{$aref}[0] or $aref->[0].
a print statement does not instantiate an object. What is meant by the implicit creation is you don't need to predefine the variable before assigning to it. Since print does not assign the variable is not created.
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.