1

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.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Eric Fossum
  • 2,395
  • 4
  • 26
  • 50
  • What you want to do is somewhat outside of the mainstream. It **is** possible through Perl's form of monkeypatching, but it's not going to be pretty. It's far more common to simply inherit from `Oscope` or make functions that take `Oscope` parameters. – Max Lybbert Mar 01 '14 at 00:47

4 Answers4

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

should be

Oscope::Acquire->new('port', 'COM3')
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • That said, I'm not convinced that inheritance is appropriate here. – ikegami Feb 28 '14 at 17:18
  • Yeah, that's the common example on the internet, but I want to expand the Oscope object with new features. Maybe I'm completely off with this parent/base thing. – Eric Fossum Feb 28 '14 at 17:21
  • 2
    @EricFossum: It would be best if you took a step back and described what it is that you want to achieve. It is disingenuous to show code that you know doesn't abide by the documentation and ask why it doesn't work. – Borodin Feb 28 '14 at 23:27
0

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.

Community
  • 1
  • 1
alexmac
  • 239
  • 2
  • 9
0

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.

Max Lybbert
  • 19,717
  • 4
  • 46
  • 69
  • Thanks for the info, just what I needed. Also, I can't believe monkey patch is a technical term(thanks Perl community). – Eric Fossum Mar 04 '14 at 00:09
  • I'm not sure who came up with the term "monkey patch." I think it's less common in Perl than some other languages. – Max Lybbert Mar 04 '14 at 01:05
-2

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;
Eric Fossum
  • 2,395
  • 4
  • 26
  • 50