Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Best way to implement Inline::C/Pure Perl function in a module?

by uG (Scribe)
on Oct 25, 2012 at 21:26 UTC ( [id://1000947]=perlquestion: print w/replies, xml ) Need Help??

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

By best, I suppose I really mean transparent. I have a module SomeModule.pm, which exports a function, ed(). It also has some helper methods that call ed(), as it does all the heavy lifting.

Now I have Inline::C code for ed() (added to the end of SomeModule.pm) and i'd like for the Inline::C ed() function to be exported and used by SomeModule.pm's helper methods if Inline::C is installed, otherwise export/use the Perl version of ed().

So I wonder what the best way to handle the situation is. Text::CSV_XS appears to set an env variable, but that doesn't seem ideal. Another solution uses eval { require Inline } and checks $@, but checking $@ doesn't seem ideal either (I see that in rare cases $@ gets modified).

Neither solution seems to be a very modern, elegant approach. What are some better ways to handle this?

  • Comment on Best way to implement Inline::C/Pure Perl function in a module?

Replies are listed 'Best First'.
Re: Best way to implement Inline::C/Pure Perl function in a module?
by syphilis (Archbishop) on Oct 26, 2012 at 00:06 UTC
    I think I would do it thusly:
    use strict; use warnings; eval { require Inline; Inline->import (C => Config => BUILD_NOISY => 1); require Inline; Inline->import (C =><<' EOC'); int foo() { warn("Using Inline\n"); return 42; } EOC }; # If Inline is unavailable, foo() simply calls # the sub bar() pure perl implementation. if($@) { *foo =\&bar; } sub bar { warn("Using Pure Perl Implementation\n"); return 42; } my $x = foo(); print "$x\n";
    If Inline::C is not available, that uses the pure-perl implementation of foo() and outputs:
    Using Pure Perl Implementation 42
    Otherwise, it uses the the Inline::C implementation of foo() and outputs:
    Using Inline 42
    NOTE: Running that script with Inline support will also output the C compilation report - but only for the *first* running, of course.
    Note also that those who have Inline::C can still access the pure-perl implementation of foo() if they wish, by directly calling bar().

    Cheers,
    Rob

      Of all the people to who could have answered :)

      I applied this method to my Makefile.PL as well. I was hoping to get the compile out of the way immediately, but I don't think Module::Install likes it. I'm not sure if I should keep playing around with it or just go back to ExtUtils...

      make: *** No rule to make target `Damerau.inl', needed by `pure_all'. Stop.

      use inc::Module::Install; name 'Some-Module'; all_from 'lib/SomeModule.pm'; readme_from 'lib/SomeModule.pm', 1; auto_manifest; auto_set_repository; auto_license; test_requires 'Test::More'; recommends 'Inline::C'; eval { require Inline; Inline->import( C => Config => BUILD_NOISY => 1 ); }; if($@) { WriteAll(); } else { WriteAll( inline => 1 ); }
        I applied this method to my Makefile.PL as well

        I think that all you can really do at the Makefile.PL stage is to eval{require Inline::C}; and use the result of that to determine whether Inline is available.
        Then you need to have 2 versions of SomeModule.pm - one rendition that caters for the availability of Inline, and one that caters for the absence of Inline support.

        One other feature of the approach I initially outlined is that Inline::C can be installed *after* SomeModule.pm has been installed, and the Inline::C version of your ed() function is then immediately available - without any need to build/install SomeModule.pm all over again.
        Of course, it does mean that the final compilation of the C code won't take place until the first time that SomeModule.pm has been loaded, *after* make install has been run.

        Other options include doing away with the Inline dependency completely and just re-structuring your module as a normal type of XS distro. (I use InlineX::C2XS for that.)

        I've no experience with inc/Module/Install ... except for some bad experiences where it has been thrust upon me by some module that I happen to be wanting to install.

        Cheers,
        Rob

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1000947]
Approved by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2024-04-25 07:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found