1

I have been scratching my head for about an hour for trying to get a .pm to work as a module for me.

My issue is quite simple.

The story:

  1. I have made a package and used Moose for OOP.
  2. I have saved the package, My::FileIO in the home directory under a common dir for all such custom modules in the form /home/USER/DIRECTORY/My/FileIO.pm. In fact, this was done after I used Module::Starter and used perl Makefile.PL which installed it in that format.
  3. I used an external script to test the module. In that, I used use lib '/home/USER/DIRECTORY/' and then confirmed the presence of the module by checking %INC which yielded the correct filename value. This led me to conclude that perl had loaded the module without any complaints.
  4. I tried to use this module by My::FileIO and the testing script had not complained at that time as well.
  5. The testing script failed after I used the constructor in the Moose way, my $test = My::FileIO->new() and this is what it threw - Can't locate object method "new" via package "My::FileIO" (perhaps you forgot to load "My::FileIO"?) at line 1.
  6. I tried to make a mock subroutine named init and it failed too.
  7. The author of Perl Maven however succeeds using these codes (https://perlmaven.com/object-oriented-perl-using-moose)

His testing script

use strict;
use warnings;
use v5.10;

use Person;

my $teacher = Person->new( name => 'Joe' );
say $teacher->name;

His test module

package Person;
use Moose;

has 'name' => (is => 'rw');

1;

Summary:

  1. The testing script is able to load the module successfuly.
  2. I am not able to use the package at all.

This is the assumed FileIO.pm

package My::FileIO; 
use feature 'state'; 
use List::Util qw(max); 
use Data::Dumper; 
use Moose;
use Type::Params qw(compile);
use Type::Utils; 
use Types::Standard qw(Str FileHandle Int HashRef ArrayRef Maybe);

[ ALL THE CODE ]

1;

Full code is at https://pastebin.com/1kxiPazd

This is my testing file - test.pl

use lib '/home/USER/DIRECTORY';
use My::FileIO; 

$test = My::FileIO->new() # Fails 

What am I doing wrong? I made a mock module like Perl Maven's and tried testing it and it failed too.

Update - I apologize for the silly errors in my writeup.

  • 1
    If it's failing at `new` instead of failing at `use`, it's finding the file OK. Are you sure the package name `My::FileIO`, the file name `My/FileIO.pm`, and the class name you're calling `new` on all correspond correctly? Including differences with uppercase and lowercase? – tobyink Oct 10 '20 at 22:14
  • 1
    Tip: When you have a central location into which you install modules (i.e. `/home/USER/DIRECTORY`), it makers more sense to use env var `PERL5LIB` (`export PERL5LIB=/home/USER/DIRECTORY`) than to use `use lib`. – ikegami Oct 11 '20 at 00:45
  • I have pasted the head of actual code. FileIO.Pm's path is /home/USER/DIRECTORY/My/FileIO.pm containing the class My::FileIO. – user9111001 Oct 11 '20 at 03:48
  • @user9111001 yeah but the error message you said you got is `Can't locate object method "new" via package "My::Test" (perhaps you forgot to load "My::Test"?) at line 1.` which is referencing an entirely different class name (My::Test instead of My::FileIO) so I'm not confident that you're using the correct class name. – tobyink Oct 11 '20 at 09:53
  • Also, checking your full code, you seem to do this a lot: `state $check = compile($sometype); my $somevar = shift; $check->($mode);` but you could just do this: `my $somevar = $sometype->(shift);` and it'll be a lot faster. `compile` is intended to be used for creating a check to check the whole of `@_` at once; it's mega-overkill for just checking a single variable. – tobyink Oct 11 '20 at 09:57
  • @tobyink. You have raised a valid point. I was doing that in a bit of an idiomatic manner as presented on the doc. – user9111001 Oct 11 '20 at 16:15
  • So ... I copied your module from the link. The package name is `My::FH`. I made a directory named `My` and placed that file in it, with the name `FH.pm`. When I load that module (`use My::FH;`) and create an object it works without trouble. I don't know what you're getting wrong, but it's likely about naming vs. placement. Perhaps see [this post](https://stackoverflow.com/a/54433246/4653379) – zdim Oct 11 '20 at 20:48
  • Notes to the above comment: (1) To load a module placed in a directory which is in the directory of the script, you have to tell perl to search the directory of the script as well (it doesn't by default in modern Perl versions). Best way: `use FindBin qw($RealBin); use lib $RealBin;`. Now you can say `use My::FH;` (if there's directory `My` in your script's directory and `FH.pm` in it). (2) To create an object in that module you need `My::FH->new(filename => valid_file_name);`. So you _must_ supply a valid filename (such file must exist) – zdim Oct 11 '20 at 20:51
  • @user9111001 I wrote the doc :) – tobyink Oct 14 '20 at 23:31

1 Answers1

3

What you posted at the bottom will work assuming the full path of the file you called FileIO.pm is /home/USER/DIRECTORY/My/FileIO.pm.

The code you posted at the bottom is clearly not what you used in your test that gave error. The error message you provided said you used -e rather than using test.pl, and it said you tried to create an object of class My::Test rather than My::FileIO.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • I apologize about that. However, it acts up similarly when not using -e. – user9111001 Oct 11 '20 at 03:44
  • Feel free to let me know when you fix the question. It still doesn't contain code you actually ran. Alternatively, provide the (unedited) output of `cat test.pl; cat /home/USER/DIRECTORY/My/FileIO.pm; ./test.pl` – ikegami Oct 11 '20 at 03:53
  • You could check the full code @ikegami. – user9111001 Oct 11 '20 at 16:15
  • 1
    You have yet to post a demonstration of problem (minimal or otherwise). And you already know how to fix your problem: Use the code you posted at the bottom of your answer. I can't tell what you did wrong because 1) There's too much contradictory information about what code you actually ran, and 2) you haven't even provided the error message you got. I'm not sure what more you want. – ikegami Oct 11 '20 at 19:33