Perl: Return hashref from function does not work

211 views Asked by At

I was fooling around with some obfuscated code that doesn't do anything useful when I encountered some strange behaviour I did not understand.

Here's my code.

no strict;
sub foo{1&&{${$_[0]},${$_[0]}}}say map {&${${_}}(${_})->{${${_}}}}map{\$_}qw(foo);

And in indented:

no strict;
sub foo {
  1 && { ${$_[0]} => ${$_[0]} }
}
say map { &${ ${_} }( ${_} )->{ ${ ${_} } } }
  map { \$_ } qw (foo);

What it should do is take the string foo, build a reference to it, and then call the function with that name (&foo). That function should return a hashref where both key and value are said foo string. After that, it prints the value of the returned hashref's key foo, which is foo.

So far, so good. Not useful, but still fun. The strange thing is, when I remove the 1 && part in the sub, it returns a list despite the curlies, and I have no clue why it does that.

If I just say sub foo { { 'foo'=>'foo' } } it returns the reference. Why doesn't it in my case? And furthermore, why does it when I add 1 &&?

1

There are 1 answers

3
dgw On BEST ANSWER

Without the 1 && part the curly braces are interpreted as a block thus returning a list. With the additional part the perl interpreter makes an anonymous hashreference as desired.

Instead of the 1 && you could also use a simple + to help the perl interpreter:

sub foo {
  +{ ${$_[0]} => ${$_[0]} }
}