Curly bracket in between the string "name" means in Perl? - perl

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")

Related

Perl assign array elements to hash user defined key

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

Error using intermediate variable to access Spreadsheet::Read sheets

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.

What is the difference between `$this`, `#that`, and `%those` in Perl?

What is the difference between $this, #that, and %those in Perl?
A useful mnemonic for Perl sigils are:
$calar
#rray
%ash
Matt Trout wrote a great comment on blog.fogus.me about Perl sigils which I think is useful so have pasted below:
Actually, perl sigils don’t denote variable type – they denote conjugation – $ is ‘the’, # is
‘these’, % is ‘map of’ or so – variable type is denoted via [] or {}. You can see this with:
my $foo = 'foo';
my #foo = ('zero', 'one', 'two');
my $second_foo = $foo[1];
my #first_and_third_foos = #foo[0,2];
my %foo = (key1 => 'value1', key2 => 'value2', key3 => 'value3');
my $key2_foo = $foo{key2};
my ($key1_foo, $key3_foo) = #foo{'key1','key3'};
so looking at the sigil when skimming perl code tells you what you’re going to -get- rather
than what you’re operating on, pretty much.
This is, admittedly, really confusing until you get used to it, but once you -are- used to it
it can be an extremely useful tool for absorbing information while skimming code.
You’re still perfectly entitled to hate it, of course, but it’s an interesting concept and I
figure you might prefer to hate what’s -actually- going on rather than what you thought was
going on :)
$this is a scalar value, it holds 1 item like apple
#that is an array of values, it holds several like ("apple", "orange", "pear")
%those is a hash of values, it holds key value pairs like ("apple" => "red", "orange" => "orange", "pear" => "yellow")
See perlintro for more on Perl variable types.
Perl's inventor was a linguist, and he sought to make Perl like a "natural language".
From this post:
Disambiguation by number, case and word order
Part of the reason a language can get away with certain local ambiguities is that other ambiguities are suppressed by various mechanisms. English uses number and word order, with vestiges of a case system in the pronouns: "The man looked at the men, and they looked back at him." It's perfectly clear in that sentence who is doing what to whom. Similarly, Perl has number markers on its nouns; that is, $dog is one pooch, and #dog is (potentially) many. So $ and # are a little like "this" and "these" in English. [emphasis added]
People often try to tie sigils to variable types, but they are only loosely related. It's a topic we hit very hard in Learning Perl and Effective Perl Programming because it's much easier to understand Perl when you understand sigils.
Many people forget that variables and data are actually separate things. Variables can store data, but you don't need variables to use data.
The $ denotes a single scalar value (not necessarily a scalar variable):
$scalar_var
$array[1]
$hash{key}
The # denotes multiple values. That could be the array as a whole, a slice, or a dereference:
#array;
#array[1,2]
#hash{qw(key1 key2)}
#{ func_returning_array_ref };
The % denotes pairs (keys and values), which might be a hash variable or a dereference:
%hash
%$hash_ref
Under Perl v5.20, the % can now denote a key/value slice or either a hash or array:
%array[ #indices ]; # returns pairs of indices and elements
%hash{ #keys }; # returns pairs of key-values for those keys
You might want to look at the perlintro and perlsyn documents in order to really get started with understanding Perl (i.e., Read The Flipping Manual). :-)
That said:
$this is a scalar, which can store a number (int or float), a string, or a reference (see below);
#that is an array, which can store an ordered list of scalars (see above). You can add a scalar to an array with the push or unshift functions (see perlfunc), and you can use a parentheses-bounded comma-separated list of scalar literals or variables to create an array literal (i.e., my #array = ($a, $b, 6, "seven");)
%those is a hash, which is an associative array. Hashes have key-value pairs of entries, such that you can access the value of a hash by supplying its key. Hash literals can also be specified much like lists, except that every odd entry is a key and every even one is a value. You can also use a => character instead of a comma to separate a key and a value. (i.e., my %ordinals = ("one" => "first", "two" => "second");)
Normally, when you pass arrays or hashes to subroutine calls, the individual lists are flattened into one long list. This is sometimes desirable, sometimes not. In the latter case, you can use references to pass a reference to an entire list as a single scalar argument. The syntax and semantics of references are tricky, though, and fall beyond the scope of this answer. If you want to check it out, though, see perlref.

Why does an undef value become a valid array reference in 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.

Why does my Perl print show HASH(0x100a2d018)?

Here I am thinking I know how to use lists in Perl, when this happens. If I do this (debugging code, prettiness not included):
#! /usr/bin/perl -w
use strict;
my $temp1 = "FOOBAR";
my $temp2 = "BARFOO!";
my #list = { $temp1, $temp2 };
print $temp1; #this works fine
print $list[0]; #this prints out HASH(0x100a2d018)
It looks like I am printing out the address of the second string. How do I get at the actual string stored inside the list? I assume it has something to do with references, but dunno for sure.
my #list = { $temp1, $temp2 };
should be
my #list = ( $temp1, $temp2 ); # Parentheses instead of curly braces.
What your original code did was store a reference to a hash {$temp1 => $temp2} into #list's first element ($list[0]). This is a perfectly valid thing to do (which is why you didn't get a syntax error), it's just not what you intended to do.
You already got the answer to your question, don't use {}, because that creates an anonymous hash reference.
However, there is still the matter of the question you didn't know you asked.
What is the difference between an array and a list in Perl?
In your question, you use the term 'list' as if it were interchangeable with the term array, but the terms are not interchangeable. It is important to understand the what the difference is.
An array is a type of variable. You can assign values to it. You can take references to it.
A list is an ordered group of zero or more scalars that is created when an expression is evaluated in a list context.
Say what?
Ok, conisder the case of my $foo = (1,2,3). Here $foo is a scalar, and so the expression (1,2,3) is evaluated in a scalar context.
On the surface it is easy to look at (1,2,3) and say that's a literal list. But it is not.
It is a group of literal values strung together using the comma operator. In a scalar context, the comma operator returns the right hand value, so we really have ((1 ,2),3) which becomes ((2),3) and finally 3.
Now my #foo = (1,2,3) is very different. Assignment into an array occurs in a list context, so we evaluate (1,2,3) in list context. Here the comma operator inserts both sides into the list. So we have ((1,2),3) which evaluates to (list_of(1,2),3) and then list_of(list_of(1,2),3), since Perl flattens lists, this becomes list_of(1,2,3). The resulting list is assigned into #foo. Note that there is no list_of operator in Perl, I am trying to differentiate between what is commonly thought of as a literal list and an actual list. Since there is no way to directly express an actual list in Perl, I had to make one up.
So, what does all this mean to someone who is just learning Perl? I'll boil it down to a couple of key points:
Learn about and pay attention to context.
Remember that your array variables are arrays and not lists.
Don't worry too much if this stuff seems confusing.
DWIM does, mostly--most of the time the right things will happen without worrying about the details.
While you are pondering issues of context, you might want to look at these links:
Start with the discussion of context in Programming Perl. Larry et alia explain it all much more clearly than I do.
Perlop means something entirely different when you pay attention to what each operator returns based on context.
A nice discussion of scalar and context on Perlmonks.
An short introductory article about context: Context is Everything.
MJD explains context.
The perldoc for scalar and wantarray