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

Hello Monks, I have need of some advice...

I am using a non-Moose object (Device::WH1091) which is mature code and works just fine. It uses Inline and has some c code in __DATA__ at the end of the module.

While attempting to debug the issue described below I also wrapped the object into a small Moose class which I named WH1091Moose so I can unambiguously make it an attribute of something else as in...

has 'weather' => (is => 'ro', isa => 'MyApp::WH1091Moose', required => + 1,default => sub {Myapp::WH1091Moose->new() } );

...and that works very nicely too. In both cases they create an _Inline directory in the current working directory and the compiled c is written to that directory.

I have written a monitoring system which allows me to plug in different roles (using with_traits) corresponding to the different hardware I wish to monitor and that has been working well with various different devices for a year or two. But this is the first time I have written a role for a device that includes an attribute that uses Inline and that is the only difference I can think of between working and non-working modules.

When I create the device using a line like this...

my $device =  MyApp::Device->with_traits( $model )->new( $refParamsHash );

...there is no error but the _Inline subdirectory is not created

When I use the role I get the error..

caught error: Undefined subroutine &Device::WH1091::getweather called +at /usr/local/share/perl5/Device/WH1091.pm line 71.

...where getweather is the c function called by the perl in Device::WH1091 module

I read somewhere that Moose implements traits by taking the module name and munging it to form a new, unique module name and also that Inline creates a directory tree that corresponds to the module name within the _Inline subdirectory .

I am wondering if the two different dependencies on the module's name are clashing and causing it to fail.

Much as I would like to include some simple code to demonstrate this I know the WH1091 module will fail unless the correct hardware is connected.

However, if in the Monks' opinion all should work I will try to write something simple that uses Inline and demonstrate it. Might take a week or several before I am confident I know how to write code for Inline

Thanks, Monks for any advice you can give

Replies are listed 'Best First'.
Re: Can code using Inline and Inline::C be used as a Role with_traits in Moose?
by Myrddin Wyllt (Hermit) on Sep 05, 2015 at 23:20 UTC

    I would say that the key fact is that the _Inline subdirectory isn't being created - if there was a naming clash at the root of the problem, I might expect the directory to be created and then later code not to be able to find it, but that's just a wild guess.

    As the C code doesn't change, and the error message indicates that the missing subroutine is being looked for in the Device::WH1091 namespace, would it be possible to point the environment variable PERL_INLINE_DIRECTORY at one of the _Inline directories that were built earlier?

    It may be possible that your problem prevents the compiled C being created, but will be able to use it if it already exists and can be found.

      Thank you, Myrddin, for the suggestion. I tried it but it didn't work.
Re: Can code using Inline and Inline::C be used as a Role with_traits in Moose?
by Anonymous Monk on Sep 06, 2015 at 08:26 UTC

    ...and that works very nicely too. In both cases they create an _Inline directory in the current working directory and the compiled c is written to that directory.

    Um, you're only supposed to compile dlls once, when you install the module, not every time you run it -- extract the XS file Inline generates and get rid of Inline when uploading to CPAN

    See

    Re^2: How to get at perl's options in a program

    InlineX::XS - Auto-convert Inline::C based modules to XS, InlineX::C2XS

    InlineX::C2XS - Convert from Inline C code to XS

      Thank you, Anonymous, for your comments.

      My target is Linux so I think the point about compiling dlls is moot although please correct me if I am mistaken.

      Thanks, though, for the links to the XS converters. I will try them out and reply again if and when I have something working.

      At first glance it looks like the original Device::WH1091 module is in the wrong format to use without modification so I might as well try to work out what it does and see if I can re-write it to libusb 1.0 instead of the now deprecated libusb 0.1, which is the version it currently uses.

      ...I may be some time.

        My target is Linux so I think the point about compiling dlls is moot although please correct me if I am mistaken.

        Moot how?

        Why is it desireable that each CWD gets a copy of the module built for the occasion?

        Why is acceptable that "installing" a module isn't the end of the installation process?

        Oh look, maybe https://metacpan.org/pod/Inline#WRITING-MODULES-WITH-INLINE is slightly better than more appealing than my advice ... its certainly better than recompiling the module after installation ... but it adds a dependency for end users on Inline which isn't always easy to install (only author needs Inline to generate the XS, everybody after author doesn't need it)