http://qs321.pair.com?node_id=721195

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

Hello dear Monks,

I have a script which needs Image::Magick for some functions but not all.

I'd like to disable these functions if Image::Magick is not installed

I tried to do something like :
pseudo-code

$is_magick = 0; if ( is_installed Image::Magick ) { $is_magick = 1 }

and later

if ( $is_magick = 0 ) { print "Image::Magick functions disabled"; } else { do stuff with Image::Magick ... }

I found some post on perlmonks and other places but nothing works

stuff like

our $is_magick = 0; eval 'require GD'; if ($@) { # problems with GD, fall back to non-GD } else { # we have GD, go for it! $is_magick = 1; }

or

our $is_magick = 1; BEGIN { unless (eval "use Image::Magick") { $is_magick = 0; } }

The first example didn't change $is_magick, the second one gives me an error 500.

How can do this ?

Thanks

Have a nice day !

updated fixed typo

"There is only one good, namely knowledge, and only one evil, namely ignorance." Socrates

Replies are listed 'Best First'.
Re: disable functions if module not installed
by kyle (Abbot) on Nov 03, 2008 at 21:47 UTC

    The second one gives you "error 500" because you left out the second quotation mark for the string eval. Also, I'm guessing you're doing this on a web server since Perl itself doesn't sprout error 500. If it's under mod_perl, I wonder if there is a scoping problem. Do you use strict and warnings?

      Hi kyle and chromatic,

      yes, on a web server, the quotation mark is a typo in the post and yes I use strict and warnings.

      while trying to write a minimal code it appears that even this doesn't work

      #!/usr/bin/perl -w use strict; use warnings; use diagnostics; my $is_Magick = 0; eval "require Image::Magick"; if ($@) { # problems with GD, fall back to non-GD } else { # we have GD, go for it! $is_Magick = 1; } print "Content-type: text/html; charset=ISO-8859-1\n\n"; print $is_Magick;

      without IM it prints 0, with IM, well :

      [Mon Nov 03 23:21:35 2008] [error] [client 127.0.0.1] Deep recursion o +n subroutine "Image::Magick::AUTOLOAD" at\r [Mon Nov 03 23:21:35 2008] [error] [client 127.0.0.1] \tC:/usr/site/li +b/Image/Magick.pm line 42 (#1)\r [Mon Nov 03 23:21:35 2008] [error] [client 127.0.0.1] (W recursion +) This subroutine has called itself (directly or indirectly)\r [Mon Nov 03 23:21:35 2008] [error] [client 127.0.0.1] 100 times mo +re than it has returned. This probably indicates an\r [Mon Nov 03 23:21:35 2008] [error] [client 127.0.0.1] infinite rec +ursion, unless you're writing strange benchmark programs, in\r [Mon Nov 03 23:21:35 2008] [error] [client 127.0.0.1] which case i +t indicates something else.\r [Mon Nov 03 23:21:35 2008] [error] [client 127.0.0.1] \r [Mon Nov 03 23:21:35 2008] [error] [client 127.0.0.1] Out of memory!

      Thanks.

      "There is only one good, namely knowledge, and only one evil, namely ignorance." Socrates
Re: disable functions if module not installed
by almut (Canon) on Nov 03, 2008 at 22:25 UTC

    Something like this works for me:

    our $is_magick; BEGIN { $is_magick = eval "require Image::Magick" ? 1 : 0; }

    (my $is_magick; is fine, too, btw)

    Note that the assignment in our $is_magick = 1; in your snippet would be executed after the BEGIN block...  Also, the BEGIN block is only necessary if you need $is_magick's state to be valid early on.

      require returns true on success, and string-eval eats memory :)
      BEGIN { $is_magick = eval {require Image::Magick;}; } C:\>perl -e"print require CGI;" 1 C:\>perl -e"print require CGIshamalamadingdong;" Can't locate CGIshamalamadingdong.pm in @INC
        require returns true on success,

        yes, and false (undef) otherwise. That was the idea :)

        string-eval eats memory

        Why would that be (in this case, where the string is just a few bytes)?  Any tests/data to prove the claim?

        C:\>perl -e"print require CGI;" 1 C:\>perl -e"print require CGIshamalamadingdong;" Can't locate CGIshamalamadingdong.pm in @INC

        Not sure what this is meant to demonstrate — I thought we were talking about eval "require ...":

        $ perl -E '$ok = eval "require CGI" ? 1:0; say $ok' 1 $ perl -E '$ok = eval "require CGIshamalamadingdong" ? 1:0; say $ok' 0

        (note: swap single and double quotes if you're on Windows)

Re: disable functions if module not installed
by chromatic (Archbishop) on Nov 03, 2008 at 21:45 UTC

    We'd have to see more code to tell you why this approach doesn't work (scoping problems with our?), but you're missing a double quote in the last example. The error log should mention this.

Re: disable functions if module not installed
by pileofrogs (Priest) on Nov 03, 2008 at 22:28 UTC

    You might also want to use a block eval instead of a string eval. Block eval is for exception handling, string eval is for on-the-fly complilation.

    If you're trying to debug this while running it as a CGI, you should serously look into CGI::Carp with particular attention to fatalstobrowser. Or you could do one better and debug it at a command line. It's a much better idea to make sure it compiles at a command line and then upload it to your web server.

    --Pileofrogs

      Hi almut and pileofrogs,

      almut your code gave me an out of memory too.

      pileofrogs fatalstobrowser is on. An example of one of these block eval's ?

      Thank you.

      "There is only one good, namely knowledge, and only one evil, namely ignorance." Socrates
        almut your code gave me an out of memory too.

        Weird.  Can you just plain load the module with use Image::Magick; (or require Image::Magick;)?  In case the machine (or user limit) doesn't provide sufficient memory to load the module (which in theory could be possible), I'd expect that you get "out of memory" either way.

        An example of one of these block eval's ?
        eval { require Image::Magick }; my $is_magick = $@ ? 0 : 1;

        Read up on eval in [perlfunc].

        Short answer:

        Block

        eval { die "You commie!" };

        String

        my $death = 'die'; eval "$death \"You commie!\";"
Re: disable functions if module not installed
by Anonymous Monk on Nov 04, 2008 at 20:04 UTC
    Your first snippet of:
    our $is_magick = 0; eval 'require GD'; if ($@) { # problems with GD, fall back to non-GD } else { # we have GD, go for it! $is_magick = 1; }
    works exactly as you want, when run as written above. $is_magick is set to 0 if GD is not available and 1 if GD is available.

    That suggests that there's something about your implementation of this snippet in your module or program that prevents it from working.

    Can you provide a sample of code that you have written which demonstrates erroneous behaviour?

      Hi,

      wrote a post on the imagemagick.

      Thank you all and don't forget to have a nice day.

      "There is only one good, namely knowledge, and only one evil, namely ignorance." Socrates

        Hello dear Monks,

        answer from magick

        We may need help on this one because we're not well versed in Perl XS programming. Anyone have a solution for this problem?

        Any solution or hint on how to trace / check / fix this ?

        Have a nice day.

        "There is only one good, namely knowledge, and only one evil, namely ignorance." Socrates