I need to write my own Test module (TestOwn) that use the Test::More module.
So the code of TestOwn.pm is something like:
package TestOwn;
use Test::More;
1;
Then i try to use the package in one of my test file (test01.t);
use lib -e 't' ? 't' : 'test';
use TestOwn;
....
done_testing();
But when the test is run i have the error:
t/test01.t .. Undefined subroutine &main::done_testing
So it seems that functions in Test::More are not imported in my test file by the use TestOwn command.
By default, nothing in your module is exported into the code that calls it. This is by design, as exporting is a rather dangerous activity that could result in name clashes.
You have to define what things to export by default (and you can also give the user of the module some control of this behavior). See Exporter.
You could export the methods of another module, but this isn't really a good idea. What if someone uses your module and Test::More? A better option would be to create your own wrappers around the Test::More functions that you think are needed, then export those. But you should limit exporting as much as possible. There are better alternatives, such as using an OO design with methods. See the above documentation for more discussion of this.
The calling code can also access stuff that is not exported by using Module::function().
Related
I have a perl module named Mysql_Routines that contains various functions I use for manipulating mysql data with DBI. I export these functions as follows:
package Mysql_Routines;
use DBI;
use strict;
use warnings;
use Data::Dumper;
use Exporter qw(import);
our #EXPORT_OK = qw(connect_to insert_row get_rows);
These are accessed from other scripts and modules using the following code:
use my_modules::Mysql_Routines qw (connect_to insert_row get_rows);
This would all appear to be standard practice, as documented on Perl Maven. However, I can only then call these functions by using the module identifier or I get an error that it's an undefined subroutine. For example:
my $dbh = Mysql_Routines::connect_to('./config/mysql-local.conf');
works.
my $dbh = connect_to('./config/mysql-local.conf');
throws the following error:
Undefined subroutine &main::connect_to called
It's obviously not a huge issue, although I'd like to understand why this is happening, as I appear to have followed the correct guidelines for creating modules containing functions.
Please see my solution below. The package declaration should have included the top directory. Silly mistake.
You seem to be confused about the name of your module. Is it "Mysql_Routines" or "my_modules::Mysql_Routines"? I suspect that you want it to be called "Mysql_Routines", in which case your use my_modules::Mysql_Routines is rather unusual. Wny wouldn't you just have use Mysql_Routines?
I guess the answer is that your module lives in a directory called "my_modules". In which case, the correct approach would be to add that directory to your library search path. You could use code like:
use lib 'my_modules';
use Mysql_Routines';
I've discovered that the problem is that in the package declaration of the module I didn't include the top directory.
Changing package Mysql_Routines to package my_modules::Mysql_Routines solves the problem. With this solution the library search path does not need to be updated as was suggested as an alternative.
I already asked a similar question, but it had more to do with using barewords for functions. Basically, I am refactoring some of my code as I have begun learning about "package" and OOP in perl. Since none of my modules used "package" I could just "require" them into my code, and I was able to use their variables and functions without any trouble. But now I have created a module that I will be using as a class for object manipulation, and I want to continue being able to use my functions in other modules in the same way. No amount of reading docs and tutorials has quite answered my question, so please, if someone can offer an explanation of how it works, and why, that would go a really long way, more than a "this is how you do it"-type answer.
Maybe this can illustrate the problem:
myfile.cgi:
require 'common.pm'
&func_c('hi');
print $done;
common.pm:
$done = "bye";
sub func_c {print #_;}
will print "hi" then "bye", as expected.
myfile_obj.cgi:
use common_obj;
&func_obj('hi');
&finish;
common_obj.pm:
package common_obj;
require 'common.pm';
sub func_obj {&func_c(#_);}
sub finish {print $done;}
gives "Undefined subroutine func_c ..."
I know (a bit) about namespaces and so on, but I don't know how to achieve the result I want (to get func_obj to be able to call func_c from common.pm) without having to modify common.pm (which might break a bunch of other modules and scripts that depend on it working the way it is). I know about use being called as a "require" in BEGIN along with its import().. but again, that would require modifying common.pm. Is what I want to accomplish even possible?
You'll want to export the symbols from package common_obj (which isn't a class package as it stands).
You'll want to get acquainted with the Exporter module. There's an introduction in Modern Perl too (freely available book, but consider buying it too).
It's fairly simple to do - if you list functions in #EXPORT_OK then they can be made available to someone who uses your package. You can also group functions together into named groups via EXPORT_TAGS.
Start by just exporting a couple of functions, list those in your use statement and get the basics. It's easy enough then.
If your module was really object-oriented then you'd access the methods through an object reference $my_obj->some_method(123) so exporting isn't necessary. It's even possible for one package to offer both procedural/functional and object-oriented interfaces.
Your idea of wrapping old "unsafe" modules with something neater seems a sensible way to proceed by the way. Get things under control without breaking existing working code.
Edit : explanation.
If you require a piece of unqualified code then its definitions will end up in the requiring package (common_obj) but if you restrict code inside a package definition and then use it you need to explicitly export definitions.
You can use common_obj::func_obj and common_obj::finish. You just need to add their namespaces and it will work. You don't need the '&' in this case.
When you used the package statement (in common_obj.pm) you changed the namespace for the ensuing functions. When you didn't (in common.pm) you included the functions in the same namespace (main or common_obj). I don't believe this has anything to do with use/require.
You should use Exporter. Change common_obj to add:
use base Exporter;
#EXPORT_OK = qw/func_obj finish/;
Then change myfile_obj:
use common_obj qw/func_obj finish/;
I am assuming you are just trying to add a new interface into an old "just works" module. I am sure this is fraught with problems but if it can be done this is one way to do it.
It's very good that you're making the move to use packages as that will help you a lot in the future. To get there, i suggest that you start refactoring your old code as well. I can understand not wanting to have to touch any of the old cgi files, and agree with that choice for now. But you will need to edit some of your included modules to get where you want to be.
Using your example as a baseline the goal is to leave myfile.cgi and all files like it as they are without changes, but everything else is fair game.
Step 1 - Create a new package to contain the functions and variables in common.pm
common.pm needs to be a package, but you can't make it so without effecting your old code. The workaround for this is to create a completely new package to contain all the functions and variables in the old file. This is also a good opportunity to create a better naming convention for all of your current and to be created packages. I'm going to assume that maybe you don't have it named as common.pm, but regardless, you should pick a directory and name that bits your project. I'm going to randomly choose the name MyProject::Core for the functions and variables previously held in common.pm
package MyProject::Core;
#EXPORT = qw();
#EXPORT_OK = qw($done func_c);
%EXPORT_TAGS = (all => [#EXPORT, #EXPORT_OK]);
use strict;
use warnings;
our $done = "bye";
sub func_c {
print #_, "\n";
}
1;
__END__
This new package should be placed in MyProject/Core.pm. You will need to include all variables and functions that you want exported in the EXPORT_OK list. Also, as a small note, I've added return characters to all of the print statements in your example just to make testing easier.
Secondly, edit your common.pm file to contain just the following:
use MyProject::Core qw(:all);
1;
__END__
Your myfile.cgi should work the same as it always does now. Confirm this before proceeding.
Next you can start creating your new packages that will rely on the functions and variables that used to be in the old common.pm. Your example common_obj.pm could be recoded to the following:
package common_obj;
use MyProject::Core qw($done func_c);
use base Exporter;
#EXPORT_OK = qw(func_obj finish);
use strict;
use warnings;
sub func_obj {func_c(#_);}
sub finish {print "$done\n";}
1;
__END__
Finally, myfile_obj.cgi is then recoded as the so:
use common_obj qw(func_obj finish);
use strict;
use warnings;
func_obj('hi');
finish();
1;
__END__
Now, I could've used #EXPORT instead of #EXPORT_OK to automatically export all the available functions and variables, but it's much better practice to only selectively import those functions you actually need. This method also makes your code more self-documenting, so someone looking at any file, can search to see where a particular function came from.
Hopefully, this helps you get on your way to better coding practices. It can take a long time to refactor old code, but it's definitely a worthwhile practice to constantly be updating ones skills and tools.
I have been USEing .pm files willy-nilly in my programs without really getting into using packages unless really needed. In essence, I would just have common routines in a .pm and they would become part of main when use'd (the .pm would have no package or Exporter or the like... just a bunch of routines).
However, I came across a situation the other day which I think I know what happened and why, but I was hoping to get some coaching from the experts here on best practices and how to resolve this. In essence, should packages be used always? Should I "do" files when I just want common routines absorbed into main (or the parent module/package)? Is Exporter really the way to handle all of this?
Here's example code of what I came across (I won't post the original code as it's thousands of lines... this is just the essence of the problem).
Pgm1.pl:
use PM1;
use PM2;
print "main\n";
&pm2sub1;
&pm1sub1;
PM1.pm:
package PM1;
require Exporter;
#ISA=qw(Exporter);
#EXPORT=qw(pm1sub1);
use Data::Dump 'dump';
use PM2;
&pm2sub1;
sub pm1sub1 {
print "pm1sub1 from caller ",dump(caller()),"\n";
&pm2sub1;
}
1;
PM2.pm:
use Data::Dump 'dump';
sub pm2sub1 {
print "pm2sub1 from caller ",dump(caller()),"\n";
}
1;
In essence, I'd been use'ing PM2.pm for some time with its &pm2sub1 subroutine. Then I wrote PM1.pm at some point and it needed PM2.pm's routines as well. However, in doing it like this, PM2.pm's modules got absorbed into PM2.pm's package and then Pgm1.pl couldn't do the same since PM2.pm had already been use'd.
This code will produce
Undefined subroutine &main::pm2sub1 called at E:\Scripts\PackageFun\Pgm1.pl line 4.
pm2sub1 from caller ("PM1", "PM1.pm", 7)
main
However, when I swap the use statements like so in Pgm1.pl
use PM2;
use PM1;
print "main\n";
&pm2sub1;
&pm1sub1;
... perl will allow PM2.pm's modules into main, but then not into PM1.pm's package:
Undefined subroutine &PM1::pm2sub1 called at PM1.pm line 7.
Compilation failed in require at E:\Scripts\PackageFun\Pgm1.pl line 2.
BEGIN failed--compilation aborted at E:\Scripts\PackageFun\Pgm1.pl line 2.
So, I think I can fix this by getting religious about packages and Exporter in all my modules. Trouble is, PM2.pm is already used in a great number of other programs, so it would be a ton of regression testing to make sure I didn't break anything.
Ideas?
See my answer to What is the difference between library files and modules?.
Only use require (and thus use) for modules (files with package, usually .pm). For "libraries" (files without package, usually .pl), use do.
Better yet, only use modules!
use will not load same file more than once. It will, however, call target package's import sub every time. You should format your PM2 as proper package, so use can find its import and export function to requestor's namespace from there.
(Or you could sneak your import function into proper package by fully qualifying its name, but don't do that.)
You're just asking for trouble arranging your code like this. Give each module a package name (namespace), then fully qualify calls to its functions, e.g. PM2::sub1() to call sub1 in package PM2. You are already naming the functions with the package name on them (pm2sub1); it is two extra characters (::) to do it the right way and then you don't need to bother with Exporter either.
I am experiencing a problem with using a constant defined in a configuration file.
This is my package:
package myPackage;
require "APIconfig.pl";
APIconfig::import(APIconfig);
use constant SERVICE_URL => APIconfig::SERVICE_URL();
The configuration looks like this:
package APIconfig;
use constant SERVICE_URL => 'http://api.example.org/blah';
1;
When running this code, I get the following error:
Undefined subroutine &APIconfig::SERVICE_URL called at API.pl line 4.
I cannot use 'use' instead of 'require' because this expects the configuration file to be named .pm, and it's called .pl on a lot of servers on our network.
How can I use the package without renaming the file?
There are two differences between 'use' and 'require'. One of them affects your current problem, the other doesn't. Unfortunately you are working around one that has no effect.
The differences are:
1/ 'use' calls the import() function, 'require' doesn't.
2/ 'use' happens at compile time, 'require' happens at runtime.
You're working around the fact that 'require' doesn't call import() by calling it explicitly. This has no effect as your module doesn't export any symbols and doesn't have an import() subroutine.
You're not working around the fact that 'use' statements are executed at runtime. The problem is that "use constant SERVICE_URL => APIconfig::SERVICE_URL();" is executed at compile time and your 'require' hasn't run by then so myPackage knows nothing about APIconfig.
The (nasty, hacky) solution is to put the 'require' statement into a BEGIN block - to force it to be executed at compile time. You'll also want to remove the call to import() as that gives a runtime error (due to the absence of the subroutine).
The test files that I used to work this out are as follows:
$ cat APIconfig.pl
package APIconfig;
use constant SERVICE_URL => 'http://api.example.org/blah';
1;
$ cat api.pl
#!/usr/bin/perl
package myPackage;
BEGIN {
require "APIconfig.pl";
}
# APIconfig::import(APIconfig);
use constant SERVICE_URL => APIconfig::SERVICE_URL();
print SERVICE_URL, "\n";
$ ./api.pl
http://api.example.org/blah
The real solution is to rewrite APIconfig as a real module. You hint that you know that, but that environmental issues prevent you taking this approach. I highly recommend trying to work around those issues and doing things correctly.
That can't be possibly right - there is no subroutine import in package APIconfig. Once you're accessing symbolic names with a full package path, you don't need to export/import anyway.
The solution is to run require at compile time, before use constant. This works:
package myPackage;
BEGIN {
require "APIconfig.pl";
}
use constant SERVICE_URL => APIconfig::SERVICE_URL();
If it's a configuration file, don't make it code. I have a whole chapter in Mastering Perl about that, and there are many modules on CPAN to help you with almost any configuration format.
If it's code, why not just make it a module so you can use use. Modules are so much easier to control and manipulate within another program.
The easiest solutions are the ones where you don't swim against the tide. :)
Beyond that, use is the same as:
BEGIN {
require Module;
Module->import;
}
You just do the same thing with filename and the namespace it defines (as long as the code in the file looks like a module):
BEGIN {
require "file.pl"; # defines SomeNamespace
SomeNamespace->import;
}
I'm currently refactoring a test suite built up by a colleague and would like to use Test::Class[::Most] while doing so. As I started I figured out I could really use a couple of Moose roles to decouple code a little bit. However, it seems it's not quite possible -- I'm getting error messages like this one:
Prototype mismatch: sub My::Test::Class::Base::blessed: none vs ($) at
/usr/lib/perl5/vendor_perl/5.8.8/Sub/Exporter.pm line 896
So the question is: can I use Moose together with Test::Class and if so, how?
PS: The code goes like this:
package My::Test::Class::Base;
use Moose;
use Test::Class::Most;
with 'My::Cool::Role';
has attr => ( ... );
Test::Deep (loaded via Test::Most via Test::Class::Most) is exporting its own blessed along with a lot of other stuff it probably shouldn't be. Its not documented. Moose is also exporting the more common Scalar::Util::blessed. Since Scalar::Util::blessed is fairly common, Test::Deep should not be exporting its own different blessed.
Unfortunately, there's no good way to stop it. I'd suggest in My::Test::Class::Base doing the following hack:
package My::Test::Class::Base;
# Test::Class::Most exports Test::Most exports Test::Deep which exports
# an undocumented blessed() which clashes with Moose's blessed().
BEGIN {
require Test::Deep;
#Test::Deep::EXPORT = grep { $_ ne 'blessed' } #Test::Deep::EXPORT;
}
use Moose;
use Test::Class::Most;
and reporting the problem to Test::Deep and Test::Most.
You can squelch particular exports via (for example):
use Test::Deep '!blessed';
I've just released an updated version of Test::Most. If you install 0.30, this issue goes away.
Folks finding this page might also be interested to know about the various Test::Class-Moose mashup modules:
Test::Able
Test::Sweet
Test::Class::Moose (not yet on CPAN)
With any of these some amount of refactoring would required-- the syntax varies. HOwever, with some amount of find-and-replace you may be able to make a fairly quick transition.