in reply to Re^3: Problem conditionally making variables shared if using threads
in thread Problem conditionally making variables shared if using threads

Indeed. Also, you need to not rely on compile-time magic. This usually boils down to just not omitting parens on your calls to imported functions.

- tye        

  • Comment on Re^4: Problem conditionally making variables shared if using threads (parens)

Replies are listed 'Best First'.
Re^5: Problem conditionally making variables shared if using threads (amp)
by tye (Sage) on Feb 19, 2015 at 04:13 UTC

    Ah, after a bit of time, I realized the interplay here is more subtle than I was originally thinking.

    My general rule is that, when loading a module conditionally, you have to work to avoid relying upon compile-time magic. The most obvious case of this would be to avoid code like:

    if( $threads ) { require threads::shared; threads::shared->import(); share @foo; # No parens used }

    Because the "share @foo;" line would cause a compile-time error (if you did 'use strict;') even when that line would never be run.

    An even more glaring case is the compile-time magic of the \& sub prototype that allows:

    use Exception::Spiffy 'catch'; catch { ... };

    For conditional usage, you'd need to do it more like:

    require Exception::Spiffy; Exception::Spiffy->import('catch'); &catch( sub { ... } );

    But there is a more subtle interaction with the \[$@%] prototype of threads::shared::share(). For example, this code will likely work:

    if( $threads ) { require threads::shared; threads::shared->import(); share( \@foo ); }

    But it also might not! If some module you loaded for whatever reason loaded something that loaded something that happened to load threads::shared, then that code would fail to compile, complaining:

    Type of arg 1 to threads::shared::share must be one of [$@%] (not refe +rence constructor)

    So, to be sure your code will work, you need to write it as:

    if( $threads ) { require threads::shared; threads::shared->import(); &share( \@foo ); # The ampersand is important }

    - tye