I was wrong. Please don't use my example. Aaron wells explanation is perfect.
Apologies for the confusion. -Raj On Thu, Apr 14, 2016 at 11:15 AM, Aaron Wells <chacewe...@gmail.com<mailto:chacewe...@gmail.com>> wrote: Hi Kenneth, Welcome aboard (for the nth time)! The replies on this thread have been helpful, but they haven’t really addressed the underlying issue, which is that there’s subscripting, then there’s dereferencing. I’ll try to keep my explanation brief, but first a solution: $confused = [ bless({ Id => [ '01tC0000003udXAIAY', '01tC0000003udXAIAY' ], type => 'Product2' }, 'sObject') ]; # strictly speaking, this is the way to do it $way1 = ${ ${ ${ $confused }[0] }{Id} }[0]; # a cleaner way to do it $way2 = $confused->[0]->{Id}->[0]; # an even cleaner way to do it $way3 = $confused->[0]{Id}[1]; print $_, "\n" for $way1, $way2, $way3; # okay, let’s pretend you want all the ids @ids = @{ $confused->[0]{Id} }; print $_, “\n” for @ids; The first thing to realize is that data structure (hash/array) references, or any kind of reference for that matter, is stored in a scalar. I’m sure you realize this. So: @array = qw(foo bar boo baz); $array_ref = \@array; print “$_\n” for @{ $array_ref }; # prints all the strings in the dereferenced $array_ref But then there’s dereferencing context. In general, dereference syntax is: [SIGIL]{ $scalar_container } So: %{ $hashref } @{ $arrayref } ${ scalar_ref } And when retrieving from a data structure, you can specify whether you want a slice or a singular value: @values = @{ $arrayref }; # or, @$arrayref $count = @{ $arrayref }; # or, @$arrayref $single_val = ${ $arrayref }[0]; # or $$arrayref[0], or $arrayref->[0] @one_val_slice = @{ $arrayref }[0]; # or @$arrayref[0], or ( $arrayref->[0] ) @three_val_slice = @{ $arrayref }[0..2]; # or @$arrayref[0..2] Fundamentally, arrays and hashes can only hold scalar values. All a hash ref or array ref is, is a scalar value that acts like a remote control, shortcut, or pointer to a multiple value data structure. Other languages hide the “reference” concept behind the interface, but Perl is pretty explicit about it. What it boils down to, is that whenever you retrieve a value from a data structure, it’s going to be a scalar: either a string, a number, or a reference of some sort. Then if what you’ve gotten is a reference, and you want to get values out of it, you need to dereference that, as I’ve shown in the last example ( [SIGIL]{ $ref }, etc. ). $way1 above shows explicitly the chain of dereferencing that happens as you pull values out of a data structure, level by level. It’s not pretty, but it gives you a good idea of what’s going on: dereference an array ref to get to a hash ref; dereference a hash ref to get to an array ref; dereference that array ref to get to its first, second value, etc. Fortunately there’s syntactic sugar: the -> operator (see $way2). The -> arrow dereferences the reference you use it on, then you subscript to the right of it to tell perl which value you want out. Just remember, you always get back a scalar, (string, num, or ref), so what you get back needs to be dereferenced if it’s some kind of container. That’s nice, but it’s not that nice, so Perl goes a step further with nested dereferencing (see $way3). The rule is this: if you’ve already dereferenced with an arrow and a subscript, subsequent subscripts are assumed to dereference the value they operate on. This is a very good thing. It makes handling nested data structures way easier. Okay one more thing before I wrap up, and this one’s for free. If you want to get multiple values out of a nested data structure you got using pointer syntax, you need to wrap the whole thing in a dereference operator. This follows from: 1. $some->{really}{deeply}{nested}{array} 2. @values = @{ $hashref }{‘I’, ‘want’, ‘these’, ‘keys’} # or if it’s an array: @{ $arrayref }[4..10] Therefore: @slicy = @{ $some->{really}{deeply}{nested}{array} }[2..17]; print “$_\n” for @slicy; All things considered, this isn’t bad. As a practice, I stick with way 3 for retrieval, then dereference if I need slices. This makes for cleaner code. Other languages make things like this easier to pick up, but I think Perl’s really nice in the long run because you can think explicitly in terms of references (like you can in C). Other dynamic, high-level languages don’t give you this kind of freedom. I suggest reading up on references again: https://docs.google.com/viewer?url=http%3A%2F%2Fblob.perl.org%2Fbooks%2Fbeginning-perl%2F3145_Chap07.pdf<https://docs.google.com/viewer?url=http://blob.perl.org/books/beginning-perl/3145_Chap07.pdf> Thanks and happy Perling! Aaron On Apr 13, 2016, at 6:29 PM, Kenneth Wolcott <kennethwolc...@gmail.com<mailto:kennethwolc...@gmail.com>> wrote: Hi; I have the following output from Data::Dumper and I want to extract the first string that the "Id" name points to. $VAR1 = [ bless( { 'Id' => [ '01tC0000003udXAIAY', '01tC0000003udXAIAY' ], 'type' => 'Product2' }, 'sObject' ) ]; So if the data structure is contained in a Perl variable called $data, then I think that this is a reference to a hash. So I need to do something like "@{$data}" to get to the hash. But I want the "Id" element of the hash so I want something like @{$data}->{'Id'} But that's the array, so what about ${@{$data}->{'Id'}}[0] But that isn't right either. I'm either getting an undefined reference to a hash error or not a scalar reference error. Thanks, Ken Wolcott -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org<mailto:beginners-unsubscr...@perl.org> For additional commands, e-mail: beginners-h...@perl.org<mailto:beginners-h...@perl.org> http://learn.perl.org/