@ISA and @EXPORT_OK are should be globals; the lexical variables @ISA and @EXPORT_OK are different variables and do not influence Exporter.
doing
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
$cat
$cleartool
$chkconfig
) ;
will fix the problem
| [reply] [d/l] |
Thanks Joost, now it works :-)
Bye,
Ron.
| [reply] |
Nearly there! The @ISA and @EXPORT_OK should be 'our' variables (not my). This is so that the Exporter module can see them. I see that you have tried to use a group tag (:DEFAULT) in the use statement, this has to be defined in the module itself using:
our %EXPORT_TAGS = ('DEFAULT' =>[ qw( list of symbols ) ],
# Maybe other tags
);
Exporter::export_ok_tags(qw(DEFAULT any_others));
| [reply] [d/l] |
I think you have a few questions within the same node. First off, what are you trying to do? There are many ways to accomplish some of these commands in Perl. For instance, have a look at CfgTie::TieRCService for using chkconfig. There is also linux admin which is a Term:CLUI module example script which can be expanded upon based on your knowledge of Perl.
There are also many CPAN modules that do basic linux commands. Check out this node for some examples: Any perl modules for handling system operations
Also, when importing functions into a script, you will want to do something like the following:
use Benchmark qw( cmpthese );
Note the name of the function has no & which is generally used in front of a subroutine to show that it is a subroutine. | [reply] [d/l] [select] |
I would actually go a different way here. Instead of using variables, use functions. And don't return the string, accept the arguments. This would allow you to do things such as swap out implementations later. So, instead of:
system($cp, $from, $to);
call:
cp($from, $to);
And then your function can start by just calling:
sub cp {
system('/bin/cp', @_);
}
but later, it can become:
sub cp {
require File::Copy;
File::Copy::cp(@_); #doesn't work for wildcards, I think.
# File::Copy::cp(map {glob $_}, @_) # <-- might be needed for wildca
+rds
}
Similarly for other commands. So you can't convert everything at once to pure perl. No big deal. You can convert what you find you need to, when you need to.
Reasons for this approach:
- Speed. Oftentimes, doing stuff in perl is just as fast as doing it in C. For example, copying files is more limited by disk/network speed than CPU speed, so perl will be just as fast for the copying part. But doing it in pure perl means you don't have the overhead of a fork and exec. Or more than one fork and exec if you use the shell in between. I have one perl program that literally copies dozens of GB, over 100,000 files, and this switch did affect the time it takes to perform the copies.
- Portability. You don't need to worry about different OS's and their different calling mechanisms. e.g., cp on unix/linux vs copy on windows. File::Copy will do it right on all of them. The above program I work on works on Windows (ia32, x64, ia64), AIX, Sun (SPARC, x64), HP (PA-RISC, ia64 aka IPF), and Linux (ia32, x64, ia64, ppc64, s390x). We've added multiple platforms over the last few years with basically no tweaking. We only call out to the shell when we have no other choice in perl.
- Portability. Yes, again. Different distros of Linux often do things different. While cleartool probably isn't going to move (since it's not owned by any distro), cp might. So when you move from RH to SuSE to Debian to Gentoo - or vice versa - something may have changed. By reducing your dependency on the hardcoded locations of applications, you reduce your exposure to those changes.
- It's just cool. ;-) You own your own work. And, with that, comes the flexibility to do things the way you need to. Need to handle regexp's in your copy command instead of globs? No problem! Cleartool acting funny when passed in multiple files? Just a tweak to the sub, and that can be dealt with as well (by calling it repeatedly)! You centralise your interface, making it possible to fix an external problem in a single internal location, rather than dealing with it all over your code.
At least, that's my approach. :-) | [reply] [d/l] [select] |
I got this to work, but I'm not 100% on if it would be the propper way to do it..
LinuxCommandsPaths.pm
package LinuxCommandsPaths;
use strict;
use vars qw(
@ISA @EXPORT_OK
$cat
$cleartool
$chkconfig
);
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(
$cat
$cleartool
$chkconfig
) ;
our $cat = '/bin/cat';
our $cleartool = '/usr/atria/bin/cleartool';
our $chkconfig = '/sbin/chkconfig';
1;
Test Code
#!/usr/bin/perl -iw
#
use strict;
use vars qw(
$cat $cleartool $chkconfig
);
use LinuxCommandsPaths qw($cat $cleartool $chkconfig);
print "\$cat == |$cat|\n";
print "\$cleartool == |$cleartool|\n";
print "\$chkconfig == |$chkconfig|\n";
Good Luck! SFlex,
| [reply] [d/l] [select] |
Thanks SFlex, for the code. Great help.
Bye,
Ron.
| [reply] |