hotshoe has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks,

Any thoughts regarding this error:

Type of arg 1 to Try::Tiny::catch must be block or sub {} (not referen +ce constructor)

I'm not sure what to make of it. I don't get the error on my macOS system (v5.18.2) but I first saw it tonight when I switched to running same code on Windows (v5.28.1 Strawberry Distro) and w/ ActiveState distro as well.

I'm getting the error consistently through my code, including in modules and script -- wherever try {} catch {}; is used, even if I gut the subroutine of all code except for an empty try / catch block. But oddly, no issue when I try the same in a standalone do nothing script.

Any advice appreciated!

Thanks,

-Roland.

2019-01-06 Athanasius added paragraph and code tags

Replies are listed 'Best First'.
Re: Try::Tiny complaining catch must be block or sub {} (not reference constructor)
by haukex (Archbishop) on Jan 06, 2019 at 09:27 UTC

    This starts failing on Perl v5.22:

    $ perl -MTry::Tiny -e 'sub foo {sub{}} try {} catch \&foo->()' Type of arg 1 to Try::Tiny::catch must be block or sub {} (not referen +ce constructor) at -e line 1, at EOF

    From perl5220delta:

    The & prototype character now accepts only anonymous subs (sub {...}), things beginning with \&, or an explicit undef. Formerly it erroneously also allowed references to arrays, hashes, and lists. ... In addition, the \& prototype was allowing subroutine calls, whereas now it only allows subroutines: &foo is still permitted as an argument, while &foo() and foo() no longer are.

    If you could show us the code that's causing the issue, I'm sure we can suggest an alternative that works on newer Perl versions.

      Thanks monks!

      False alarm. I needed to address the experimental push by casting my reference to array w/ @{}. It's in a different code block from try / catch block so I assumed the errors were unrelated (and they are) but fixing the one addresses the try / catch "issue".

      Experimental push on scalar is now forbidden at [mymodule] line 474, n +ear "$asset;" Type of arg 1 to Try::Tiny::catch must be block or sub {} (not referen +ce constructor) at [mymodule] line 680, near "};" Type of arg 1 to Try::Tiny::try must be block or sub {} (not reference + constructor) at [mymodule] line 680, near "};"

      I created short code sample below that illustrates the behavior in action (w/ the fix). Still not at all clear to me how the one (experimental push issue) affects the other, but I'm unblocked from making progress. Any thoughts?

      use strict; use warnings; use 5.006; use Try::Tiny; my @array = (); my $array_ref = \@array; push $array_ref, 'test'; # bugbug #push @{$array_ref}, 'test'; # <== change prev line to be like this test(); sub test { try { my $a = 1/0; } catch { print 'awww, snap!'; }; 1; } 1; __END__
        Still not at all clear to me how the one (experimental push issue) affects the other, but I'm unblocked from making progress. Any thoughts?

        I don't know for sure, but I'd suspect that the earlier error caused the parser to get confused about the rest of the program, that kind of thing happens often - one syntax error can leave the parser in a bad state, and while it may try to parse the rest of the program to report as many other errors as it can, it obviously got it wrong in this case. That's why short yet complete examples like the one you showed (thank you for that) are always incredibly useful, since if we'd known there were other errors in addition to the one you stated in the root node, the fix would have probably become obvious faster.

Re: Try::Tiny complaining catch must be block or sub {} (not reference constructor)
by AnomalousMonk (Archbishop) on Jan 06, 2019 at 07:27 UTC

    Please supply an SSCCE that produces the problem (or not, depending on Perl version).


    Give a man a fish:  <%-{-{-{-<

Re: Try::Tiny complaining catch must be block or sub {} (not reference constructor) (updated)
by haukex (Archbishop) on Jan 06, 2019 at 08:49 UTC

    I agree with AnomalousMonk that we'd need to see a short piece of example code that reproduces the issue, because I haven't been able to reproduce it myself, and I think it's a slightly strange issue.

    Update: See Re: Try::Tiny complaining catch must be block or sub {} (not reference constructor).

    must be block or sub {} (not reference constructor)

    That sounds like this (from map), although as I said I'm not sure what's triggering it in this case:

    { starts both hash references and blocks, so map { ... could be either the start of map BLOCK LIST or map EXPR, LIST. Because Perl doesn't look ahead for the closing } it has to take a guess at which it's dealing with based on what it finds just after the {. Usually it gets it right, but if it doesn't it won't realize something is wrong until it gets to the } and encounters the missing (or unexpected) comma. The syntax error will be reported close to the }, but you'll need to change something near the { such as using a unary + or semicolon to give Perl some help:
    my %hash = map { "\L$_" => 1 } @array # perl guesses EXPR. wrong my %hash = map { +"\L$_" => 1 } @array # perl guesses BLOCK. right my %hash = map {; "\L$_" => 1 } @array # this also works my %hash = map { ("\L$_" => 1) } @array # as does this my %hash = map { lc($_) => 1 } @array # and this.