Slice returned hash or access to its elements without assigning to a variable

A

Andrew

Hi,

Please help me in solving next problem(I search in FAQ bun have not
find an answer):
There is a sub foo which return hash:

sub foo{my %in=( key1=>value1
key2=>value2
key3=>value3);
}
I need to assess elements of returned hash without assigning to a
variable. Something like this:
print @&foo(){'key1','key2'};
print $&foo(){'key1'};

But this does not work: "Bareword found where operator expected"

Thanks,
Andrew
 
G

Gunnar Hjalmarsson

Andrew said:
There is a sub foo which return hash:

sub foo{my %in=( key1=>value1
key2=>value2
key3=>value3);
}

Would that be the sub? Don't think so. It doesn't even compile, and even
if it had compiled, it would have returned a list rather than a hash.

Subroutines don't return hashes, but they may return references to hashes.

perldoc perlsub
I need to assess elements of returned hash without assigning to a
variable. Something like this:
print @&foo(){'key1','key2'};
print $&foo(){'key1'};

sub foo {
my %in = ( key1=>'value1', key2=>'value2', key3=>'value3' );
\%in
}

print @{ foo() }{'key1','key2'};
 
G

Glenn Jackman

At 2005-06-11 12:35PM said:
Hi,

Please help me in solving next problem(I search in FAQ bun have not
find an answer):
There is a sub foo which return hash:

sub foo{my %in=( key1=>value1
key2=>value2
key3=>value3);
}

Strictly speaking, this returns a 6-element list, not a hash.
I need to assess elements of returned hash without assigning to a
variable. Something like this:
print @&foo(){'key1','key2'};
print $&foo(){'key1'};

But this does not work: "Bareword found where operator expected"

Coerce the returned list from foo into a hash ref, and dereference
accordingly:
sub foo { (a=>1,b=>2,c=>3) }
$b = +{foo()}->{b};
@arr = @{%{+{foo()}}}{'a','b'}
 
G

Glenn Jackman

At 2005-06-11 12:35PM said:
Hi,

Please help me in solving next problem(I search in FAQ bun have not
find an answer):
There is a sub foo which return hash:

sub foo{my %in=( key1=>value1
key2=>value2
key3=>value3);
}

Strictly speaking, this would return a 6-element list, not a hash, if it
was proper Perl.
sub foo { (a=>1,b=>2,c=>3) }
I need to assess elements of returned hash without assigning to a
variable. Something like this:
print @&foo(){'key1','key2'};
print $&foo(){'key1'};

But this does not work: "Bareword found where operator expected"

Coerce the returned list from foo into a hash ref, and dereference
accordingly:
$b = +{foo()}->{b};
@arr = @{%{+{foo()}}}{'a','b'}
 
B

Brian McCauley

Glenn said:
Coerce the returned list from foo into a hash ref, and dereference
accordingly:

Good advice
@arr = @{%{+{foo()}}}{'a','b'}

No,

@arr = @{{foo()}}{'a','b'}

Due to a bug in the Perl compiler the spurious %{} will be ignored but
it's still wrong.
 
A

axel

Gunnar Hjalmarsson said:
Subroutines don't return hashes, but they may return references to hashes.

Well, since a hash being returned gets flattened into a list, there is
no reason why this list could not be picked up in an assignment to a
hash, although it would probably not be good practice.

sub abc {
...;
%bar;
}

my %foo = abc();

Axel
 
G

Gunnar Hjalmarsson

Well, since a hash being returned

Again, a hash is never returned. The last expression that is evaluated
may be a hash, which is probably what you mean, and in list context a
hash returns a list of the keys and values. Sorry about this nitpicking,
Axel, but I believe it is motivated.
gets flattened into a list, there is no reason why this list could not
be picked up in an assignment to a hash,

One reason would be the OP's requirement to access the values without
assigning to a variable. ;-)
although it would probably not be good practice.

Right.
 
G

Glenn Jackman

At 2005-06-11 03:00PM said:
No,
@arr = @{{foo()}}{'a','b'}
Due to a bug in the Perl compiler the spurious %{} will be ignored but
it's still wrong.

Thanks for the simplication. I was flailing about with braces and types
trying to construct an example.

So, what goes into the first set of braces is a hashref, yes?
%a = (a=>1,b=>2,c=>3);
$aref = \%a;

# these are valid:
$a{b};
${a}{b};
${$aref}{b};
$$aref{b};
${\%a}{b};
 
B

Brian McCauley

Glenn said:
Thanks for the simplication. I was flailing about with braces and types
trying to construct an example.

So, what goes into the first set of braces is a hashref, yes?

Yes. (Unless it's a word).
%a = (a=>1,b=>2,c=>3);
$aref = \%a;

# these are valid:
$a{b};
${a}{b};
${$aref}{b};
$$aref{b};
${\%a}{b};

Yes.

Note that in ${a}{b}; the 'a' is treated neither as a bareword string
nor as a symbolic reference[1]. ${a}{b} is simply an affected way to
write $a{b}.

[1] Although historically, in Perl4, you could have choosen to think of
it that way if you wanted.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top