Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

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

by uG (Scribe)
on Oct 25, 2012 at 21:26 UTC ( #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?
Re: Best way to implement Inline::C/Pure Perl function in a module?
by syphilis (Canon) 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
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? | Other CB clients
Other Users?
Others exploiting the Monastery: (7)
As of 2015-07-07 08:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (87 votes), past polls