<stuff against Perl>
Okay, first thing you're doing wrong is hating on Perl before being really good at Perl, or at least having asked a person who is really good at Perl. Here's a really simple import script:
package Foo;
sub bar {...}
1;
use Foo;
Foo::bar(42);
That's literally all you need. "package Foo;" selects the namespace, and since the main program's code isn't written in the Foo namespace, you need to call Foo::bar instead of just bar. Simple as that.
Aaactually, it gets even simpler if you prefer not to use namespaces and want to do everything in the main namespace (horrible coding practice tho):
sub bar {...}
1;
use Foo;
bar(42);
Now here's the deal about namespaces: What Perl doesn't have is a "public" keyword for subroutines. And there is no default "using namespace" or "import" method to clutter your namespace. There are good reasons for this:
First of all, Perl actually allows you to redefine subroutines at runtime. This is because subroutine names (such as &foo) are technically also variables and you can overwrite them at any time (note that assigning to subroutines has different syntax than assigning to other variables). So defining them as "public" would just make no sense.
But before you complain that they shouldn't be variables: Perl's import mechanism allows a module to give its
user fine control over which variables and methods should be thrown into the user's namespace (by overwriting the appropriate subroutines with the module's own). Note that this functionality needs to be defined by the module itself, which is a bit of extra work for the module author.
But before you complain that it shouldn't be like that: Consider that there are usually many more people that use a module than people who write it. And consider that it is very awesome to just be able to write "Hey, I'd like to use this module and I'd like to import this set of functions and that set, but not that one" using a single uncluttered readable line. And that is actually feasible in a Perl module, because Perl is awesome like that. You can of course abuse this functionality for many other cool tricks and improvements of user comfortability, but that is not in the scope of this rant.
If you're worrying that writing that functionality is hard, then that's what the Exporter module is there for, it is a part of the standard Perl library and basically does all the work for you, you just need to tell it which methods to export, and you do that using @EXPORT, and if you want to allow individual things to be exported on demand, you do that using @EXPORT_OK, and if you want to group things into sets which can be exported all at once, you use %EXPORT_TAGS. That's literally all you have to do.
Finally, if you need to import modules from other directories, you really just need to write this:
use lib "path/to/lib";
use Foo;
And if you are really really bothered by having to list your subroutines manually in the @EXPORT variables, I made some "public"-style keywords for you so you don't need to do that. Just put this at the start of your module:
package YOURPACKAGEHERE;
use parent Exporter;
our (@EXPORT, @EXPORT_OK, %EXPORT_TAGS) = ();
sub public {
no strict "refs";
my ($n, $s) = @_;
*{$n} = $s;
push @EXPORT, $n;
push @EXPORT_OK, $n;
return $n;
}
sub optional {
no strict "refs";
my ($n, $s) = @_;
*{$n} = $s;
push @EXPORT_OK, $n;
return $n;
}
sub group {
my ($g, @n) = @_;
push @{$EXPORT_TAGS{$g}}, @n;
return @n;
}
Then you can define your subroutines like this:
# Will always be exported
public bar => sub {
...stuff...
...things...
}; ##Don't forget a semicolon here
# Will be exported if required
optional baz => sub {
...thangs...
};
# Add subroutines to a group to be able to import all subroutines of the same group using "use Foo qw(:features1)":
group features1 => qw(bar baz quux);
# Or you can directly add subroutines to a group right when the subroutine is defined:
group features1 => public quux => sub {
...justquuxthings...
};
TL;DR: Perl is literally the opposite of a boilerplate language, focusing on usability more than anything else. If you're doing something and it's taking more code than in other languages, at least one of the following options is true:
1) You are experiencing the small downside to a well-placed tradeoff of some simplicity for much more flexibility. In that case, there exists either a standard library module that restores the simplicity, or at least fifty CPAN modules doing the same.
2) You are writing a public module using all the good coding practices (Perl needs lots of those because it's really easy to accidentally write perfectly unreadable code).
3) There are many many better ways to do what you're doing than how you're doing it right now.