in reply to Dereferencing code refs with & vs. ->()

I prefer &$thingy over $thingy->(). It's one character less (three less if you're not passing arguments), and it's more general. This works:
&{ Block returning a code reference }
but this doesn't:
{ Block returning a code reference }->();

That's why I also prefer:

$$hash_ref{key} = $$array_ref[1];
over
$hash_ref->{key} = $array_ref->[1];
-> is not a shortcut. It's a detour ;-)

Replies are listed 'Best First'.
Re^2: Dereferencing code refs with & vs. ->()
by demerphq (Chancellor) on Sep 23, 2005 at 13:11 UTC

    I prefer &$thingy over $thingy->().

    Aren't these apples and oranges?

    sub t { my $sub=shift; $sub->(); } sub u { my $sub=shift; &$sub; } t(sub{print">@_<"},1,2,3,4,5); u(sub{print">@_<"},1,2,3,4,5); _END__ >< >1 2 3 4 5<

    It's one character less (three less if you're not passing arguments), and it's more general.

    More general? Im not sure I agree with that... And im not convinced about the one character less either. Id say that for the below its actually one character more. Especially given the above point that &{EXPR}() is the equivelent of EXPR->() and not &{EXPR}

    do { sub { print 'foo' } }->(); ( sub { print 'bar' } )->();

    That's why I also prefer:$$hash_ref{key} = $$array_ref[1];

    I class that notational style as a code smell. If I have to deal with code like that the first thing I do is switch it to use the infix dereference operator. And strangely I often find that the bug I was looking for just vanishes by doing so. IOW: this style is error prone and IMO a maintenance nightmare.

    ---
    $world=~s/war/peace/g

Re^2: Dereferencing code refs with & vs. ->()
by dragonchild (Archbishop) on Sep 23, 2005 at 13:17 UTC
    &{ Block returning a code reference }

    Are you saying that your code is littered with

    &{do { # stuff here sub { ... }; }};
    Because I'm not sure I like that syntax. It looks very obfuscated, to my eyes.

    $$hash_ref{key} = $$array_ref[1];

    Yes, I see that a lot in older code. The problem is that this syntax only works because of how tightly $ binds vs. {} or []. You're depending on the Perl parser always guessing correctly. Maybe I'm paranoid, but I prefer not making the parser guess my intention.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      The official way of coding that is:
      ${$hash_ref}{key} = ${$array_ref}[1];
      You may leave of the braces if the content of the block is a simple variable. Perhaps you find that obfuscated, but that's actually the same rule as the first (optional) argument of print. The file handle is passed as a block, and taken as the result, but if the block is a simple variable, you may leave off the braces. If that isn't obfuscated, why is the code I presented obfuscated? Or is it that you aren't used to it, and call anything you aren't used to obfuscated?

      If you want to take a slice of a hash or an array, and all you have is a reference to it, how do you do it without being "obfuscated"? I write it as:

      @$hash_ref{$key1, $key2, $key3};
      which follows naturally from accessing a single value:
      $$hash_ref{$key1};
      But
      @hash_ref->{$key1, $key2, $key3};
      doesn't work and nor does
      $hash_ref->{$key1, $key2, $key3};

      And no, my code isn't littered with

      &{do {... sub {...}}};
Re^2: Dereferencing code refs with & vs. ->()
by ambrus (Abbot) on Sep 24, 2005 at 17:53 UTC

    { Block returning a code reference }->(); doesn't work, but ( Block returning a code reference )->(); works, doesn't it?

    Also &$thingy calls the subroutine with the same @_, so it's not the same as $thingy->(), this latter is really equivalent to &$thingy(). I think you probably thought of &$thingy() anyway, as that's what's one character less than $thingy->().