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 &&
?
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: