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

You haven't used threads::shared in the current scope (package)

Isn't that accomplished by using use Module::Load::Conditional qw[can_load];?

You always have to pass a reference to threads::shared::share(); unless you disable the prototype

Disable the prototype? I'm not sure what you mean by that. Explicitly using &share($gnWarning) makes no difference, if that's what you mean.

If you know of any way to configure a program to use threads based on the perl executable being compiled with it, and not use it otherwise, other than the method I'm trying, I'd be interested to know.

Replies are listed 'Best First'.
Re^3: Problem conditionally making variables shared if using threads
by BrowserUk (Patriarch) on Feb 18, 2015 at 22:33 UTC

    From the Module::Load::Conditional POD for can_load:

    autoload

    This controls whether imports the functions of a loaded modules to the caller package. The default is no importing any functions.

    You haven't asked for the exported functions to be imported into your package.

    Disable the prototype? I'm not sure what you mean by that. Explicitly using &share...

    You got it :)

    Explicitly using &share($gnWarning) makes no difference,

    It won't if share() has not been imported into your package; unless you fully qualify it.

    If you know of any way to configure a program to use threads based on the perl executable being compiled with it, and not use it otherwise, other than the method I'm trying, I'd be interested to know.
    use Config; if( $Config{ useithreads } eq 'define' ) { ## compiled with ithreads require threads; threads->import; require threads::shared; threads::shared->import } else { ## not }

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
    In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

      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        

        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