2. About Me
• Shoichi Kaji
• CPAN SKAJI
• perl5 cpm, App::FatPacker::Simple,
Mojo::SlackRTM
• perl6 mi6, Frinfon
3. Contents
• What is App::FatPacker?
• Who uses App::FatPacker?
• How to use App::FatPacker
• Problems and solutions for App::FatPacker
• Conclusion
• See also
5. • Let’s say you want to download perl tarball.
• This script runs perfectly in your local OS X.
# download.pl
use strict;
use warnings;
use HTTP::Tiny;
my $http = HTTP::Tiny->new;
my $url = "http://www.cpan.org/src/5.0/perl-5.22.1.tar.gz";
my $res = $http->mirror($url => "perl-5.22.1.tar.gz");
if ($res->{success}) {
warn "Complete!n";
} else {
die "Failed $res->{status}";
}
6. • But, if you run it in a remote CentOS6 host,
you’ll get
• This is because the perl in CentOS6 is so old
that it does not have HTTP::Tiny in core :/
$ /usr/bin/perl download.pl
Can’t locate HTTP/Tiny.pm in @INC (@INC contains…)
7. What can we do?
• Yes, we can install HTTP::Tiny in remote host
• But it is sometimes tiresome, or even
impossible.
• Okay let’s introduce App::FatPacker by mst
now!
$ cpanm HTTP::Tiny
Successfully installed HTTP-Tiny-0.056
8. • App::FatPacker embeds HTTP::Tiny into a BEGIN
block so that we have self-contailed download.pl
# download.fatpack.pl
BEGIN {
my %fatpacked;
$fatpacked{"HTTP/Tiny.pm"} = <<'EOF';
package HTTP::Tiny;
# ... all HTTP::Tiny code ...
1;
EOF
my $class = "FatPacked::" . (0+%fatpacked);
*{$class . "::INC"} = sub {
my ($self, $pm) = @_;
if (my $content = $self->{$pm}) {
open my $fh, "<", $content;
return $fh;
}
return;
};
unshift @INC, bless %fatpacked, $class;
}
# content of download.pl...
11. Who uses App::FatPacker?
• perlbrew by gugod
• cpanm by miyagawa
• perl-build (plenv plugin) by tokuhirom
• start_server (bundled in h2o) by kazuho
12. How to use App::FatPacker
• perldoc fatpack says:
# 1. trace dependencies
fatpack trace myscript.pl
# 2. find .packlist files
fatpack packlists-for `cat fatpacker.trace` >packlists
# 3. collect pm files in ./fatlib directory
fatpack tree `cat packlists`
# 4. bundles all pm files in ./fatlib into BEGIN block of myscript.pl
fatpack file myscript.pl >myscript.packed.pl
13. Problem
• I cannot remember usage of fatpack :/
• Tracing dependencies may result in
unexpected
• Modules that I want to trace does not trace
• Modules that I do not want to trace trace
14. Solution
• I created App::FatPacker::Simple
• It completely leaves you to trace
dependencies
• It just creates a fatpacked script with all
modules in lib, local, fatlib, extlib directories
15. • It is simple, isn’t it?
# You know HTTP::Tiny is a dependency.
# So install it to ./local first
$ cpanm -nq -L ./local HTTP::Tiny
Successfully installed HTTP-Tiny-0.056
# Then just run fatpack-simple
$ fatpack-simple download.pl
-> fatpack HTTP/Tiny.pm (with perl-strip)
-> Successfully created download.fatpack.pl
16. Still problem…
• Although I said App::FatPacker::Simple leaves
you to trace dependencies, it’s sometimes
annoying.
• Let’s say your script depends on URI module. Then
$ cpanm -nq -L ./local URI
Successfully installed URI-1.71
$ fatpack-simple script.pl
-> Successfully created script.fatpack.pl
$ /path/to/5.8.5/perl script.fatpack.pl
Can’t locate parent.pm in @INC ...
17. • Solutions might be
• Use perl5.8.5 even in fatpacking process💩
• Use cpm with --target-perl option👍
$ cpm install --target-perl 5.8.5 URI
DONE install parent-0.234
DONE install URI-1.71
$ fatpack-simple script.pl
-> Successfully created script.fatpack.pl
$ /path/to/5.8.5/perl script.fatpack.pl
# WORKS!
18. Conclusion
• App::FatPacker can create a self-contained,
depencency-free perl script
• App::FatPacker::Simple + cpm may help that
• Happy hacking with perl5!
19. See also
• https://metacpan.org/pod/App::FatPacker
• https://metacpan.org/pod/App::FatPacker::Simple
• https://github.com/skaji/plenv-download (a real
example of using fatpack-simple + cpm)
• http://ks0608.hatenablog.com/entry/
2015/06/07/004313 (an explanation of require()
function, in japanese)