Domanda

I am trying to make a library of functions for my oscilloscope, but I can't seem to get other module files to play nice.

What I have is here, except the Oscope.pm file. If it's needed I can upload it too.

test.pl

# Includes
use 5.012;
use Oscope;
use Oscope::Acquire;
use warnings;

# From Oscope.pm
my $scope = Oscope->new('port', 'COM3');

# From Oscope::Acquire.pm
$scope->QueryAcquire();

Oscope/Acquire.pm

package Oscope::Acquire;

use Oscope;
use parent 'Oscope';

sub QueryAcquire
{
   my ($self) = @_;
   # Oscope.pm
   my $message = $self->Send('ACQUIRE?');
   return();
}

1;

Output

Can't locate object method "QueryAcquire" via package "Oscope" at C:\Documents and Settings\ericfoss\My Documents\Slick\Perl\tests\Test.pl line 11.

È stato utile?

Soluzione 2

I'm not going to say this is a good idea. You apparently want Oscope::Aquire to monkey patch Oscope. That is possible, but I would recommend having Oscope::Acquire export a function that takes an Oscope parameter (more information on exporting):

Oscope/Acquire.pm

package Oscope::Acquire;
require Exporter 'import';
@EXPORT_OK = qw{QueryAcquire};

use Oscope;

sub QueryAcquire
{
    my ($oscope) = @_;
    my $message = $oscope->Send('ACQUIRE?');
    return $message;
}

1;

Which you would use:

use Oscope;
use Oscope::Acquire 'QueryAcquire';

my $oscope = Oscope->new();
print QueryAquire($oscope);

However, if you really want the $oscope->QueryAcquire() syntax, and you don't want to put it in Oscope itself, you can monkey patch the module. Perl documentation refers to this as modifying the module's symbol table through a typeglob and it's apparently deprecated ("The results of creating new symbol table entries directly ... are undefined and subject to change between releases of perl"):

Oscope/Acquire.pm

package Oscope::Acquire;

use Oscope;

*Oscope::QueryAcquire = sub {
    my ($self) = @_;
    my $message = $self->Send('ACQUIRE?');
    return $message;
}

1;

I should have read my own link more closely. It appears that the approved way of doing this is to simply add methods to the Oscope package inside the Oscope/Acquire.pm file ("You can define a subroutine outside its package by explicitly qualifying the name of the subroutine"):

package Oscope::Acquire;
use Oscope;

...

sub Oscope::QueryAcquire {
    my ($self) = @_;
    my $message = $self->Send('ACQUIRE?');
    return $message;
}

1;

That is, there's no need to the typeglob.

Altri suggerimenti

Oscope->new('port', 'COM3')

should be

Oscope::Acquire->new('port', 'COM3')

Where are your lib packages, place your code there. You could also use

use lib "path"

Another explanation can be found here which answers require over lib.

Your area message says it all in that it can't find the function.

As the code stands you could just say $scope->Oscope::Acquire::QueryAcquire();, but to get the desired effect, you need to make it part of the package.

package Oscope;

sub QueryAcquire
{
   # Code here
}

1;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top