in reply to Re^5: Trying to use App::Fatpacker
in thread Trying to use App::Fatpacker

I'm a perl beginner, so I didn't.
I asked about how to do something like this manually in another thread but I got no reply there.
Thanks for the suggestion, I'll try it later today and report back.

Just to make sure, by module you mean the complete and unmodified content of the .pm file, right? I guess I need to wrap the content of each .pm in a block of some sort, right? Maybe a sub like so?
sub HTML::Strip { #content of HTML::Strip's .pm goes here }

Replies are listed 'Best First'.
Re^7: Trying to use App::Fatpacker
by Corion (Patriarch) on Nov 03, 2010 at 10:21 UTC

    No. You can wrap a whole package in a block:

    { package HTML::Strip; ... rest of HTML/Strip.pm goes here }

    The two things you need to look out for is __END__ blocks or __DATA__ blocks in the modules, and "unclosed" POD sections. You need to close the POD sections and remove everything from __END__ or __DATA__ onwards because Perl stops reading the file at these locations too.

    So if you have an example file HTML/Strip.pm

    package HTML::Strip; sub pole_slide { ... }; 1; __END__ =head1 NAME HTML::Strip =cut

    ... you'd include the following in your main program:

    package HTML::Strip; sub pole_slide { ... }; 1; package main; # use HTML::Strip; BEGIN { HTML::Strip->import() }; # rest of your main program goes here

    This is a slightly different approach than what App::Fatpacker uses, and it requires a bit more human judgement, but it involves much less Perl internals and you'll learn a bit about how packages and modules interact.

      Thank you all for the detailed information, it now seems pretty clear how this should be done.
      I did a bit of testing, and of course it's not that simple (it never is). For instance, HTML::Parser is made up of a bunch of modules that call each other, so I guess I'll need to paste each of them in my script and basically do a s/^use (.*)\;$/BEGIN \{ $1->import\(\) \}\;/ in them.
      And then of course there are the external dependencies. E.g. HTML::TokeParser has use HTML::Tagset ();, so I'll have to download HTML::Tagset as well, and any dependencies it might have... I'm starting to see why a module was written in the first place for this purpose.

      After pasting the HTML modules in my script and starting it, I got error messages about a bunch of subroutines being redefined. I think the various HTML::Parser modules contain the same subs multiple times (once in each module). So I'll either have to switch warnings and strict off, or I'll have to manually delete or rename subs. Oh joy...
      If a kind App::FatPacker user ran it on these 3 modules for me, I would be very grateful.
        ...and of course it's not that simple...
        One particular problem with HTML::Parser is that it has an XS component (compiled shared libarary code). This means you can't inline it into your script anyway. And, as far as I've understood from a quick look at the sources, App::FatPacker can't handle that either...

        In other words, to build a stand-alone distributable program, you'd need a more full-blown solution, like PAR or perl2exe.

Re^7: Trying to use App::Fatpacker
by mr_mischief (Monsignor) on Nov 03, 2010 at 10:22 UTC
    This is perhaps a little counterintuitive for a language with lots of bracketed syntax, but the package Some::Name statement creates its own namespace and such. You can have several packages in one file without extra bracketing around them.
      You can have several packages in one file without extra bracketing around them.
      but additional blocks do avoid potential name clashes of lexical variables, which are file scoped, not package scoped:

      #!/usr/bin/perl -w package X; my $name = "foo"; package Y; my $name = "bar"; __END__ "my" variable $name masks earlier declaration in same scope at...