1

I have the following perl module:

#!/usr/bin/env perl
package temp;
require Exporter;
our @ISA = ('Exporter');
our @EXPORT = qw(temp_print);
sub temp_print {
  my ($p) = @_ ;
  print "$p\n" ;
}

1;

This file is present here: ./f/temp.pm My main file is called test.pl and looks like this

#!/usr/bin/env perl
use strict;
use warnings;
use FindBin qw($Bin);
use lib $Bin;
use f::temp ;

temp_print("hi");

When I try to execute test.pl, it doesn't seem to be importing temp_print into the main package:

% ./test.pl
Undefined subroutine &main::temp_print called at ./test.pl line 8.

I'm not sure what I am missing. This seems to be pretty basic, but can't seem to figure why the subroutines from my package are not being imported. Could you help me figure out what's wrong?

backstreetrover
  • 203
  • 1
  • 11
  • The package needs namespace `package f::temp;`, for how you set it up. (Or, with `package temp;` you do `use temp;` and `use lib "$Bin/f";`) See [this post](https://stackoverflow.com/a/54433246/4653379), for example. (Note, a convention is to use CamelCase, so capitalized names.) – zdim Feb 20 '19 at 04:38
  • Indeed! That explains it. After posting, i played around and realized that the following hack works: `BEGIN { require f::temp ; temp->import ; }` Thanks for the link, wasn't aware of this naming requirement. Now I realize why my hack works, but not original code. – backstreetrover Feb 20 '19 at 05:33
  • 1
    Re "_following hack works_" --- great to see that you are trying things out, but that's really a "hack" (in the sense of "don't do that"), and I don't see why it works (it picks up `Exporter::import` ... somehow?). A normal, correct way is: (1) Correct naming, as in the linked post (2) Bring in `Exporter`'s sub `import`, which pushes the module's symbols to the caller. This is nicely done by `use Exporter qw(import);`, but it can be done via inheritance as you have it (see linked post and that question itself) – zdim Feb 20 '19 at 06:09
  • _I don't see why it works_ - It works because `require f::temp` will source the temp.pm file. Now since my original wrong code for temp.pm had `package temp`, this means `temp->import` is calling the import method of the temp package which it just sourced. How does the import method come to exist in package temp? - through inheritance since I have `our @ISA = qw(Exporter)` so all methods of Exporter are also available in package temp. Anyhow thanks for pointing me in the right direction. I dont want to do any hackery. – backstreetrover Feb 20 '19 at 06:11
  • guess are posts crossed each other. Thanks Anyhow – backstreetrover Feb 20 '19 at 06:12
  • 1
    yeah ... I totally skipped that you had inheritance ("old" way), so it does pick up the `import`. – zdim Feb 20 '19 at 06:13
  • 1
    I nearly marked this as dupe of the linked post (which it is) -- but I'm glad I didn't since this was good work on your part to figure out that way to do it. (Once :) – zdim Feb 20 '19 at 06:16

1 Answers1

1

use Exporter ... is shorthand for

BEGIN {
    require Exporter;
    Exporter->import(...);
}

By saying require Exporter instead, you are skipping the call to Exporter's import method.

You'll also have to sort out the correct package/file name problem as zdim's comment alludes to.

mob
  • 117,087
  • 18
  • 149
  • 283
  • I think you are mixing things up.`use f::temp` is shorthand for `BEGIN { require f::temp ; f::temp->import }`. The issue was as zdim pointed out that my package naming was wrong – backstreetrover Feb 20 '19 at 05:47
  • 1
    Ok .. I see what you mean `use Exporter qw(import)` would also work in test.pm instead of `require Exporter`. But my usage of `require Exporter` also works since I have additionally done `our ISA = qw(Exporter)` thereby f/test.pm will get all methods of Exporter through inheritance – backstreetrover Feb 20 '19 at 06:05
  • Yeah this answer isn't really the problem. There is no reason to call Exporter's import method except to import the import method, which is preferable to inheriting from Exporter, but not necessary when doing so. – Grinnz Feb 20 '19 at 17:59