Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Print perl source code in compiled script...

by bcarroll (Pilgrim)
on Feb 09, 2012 at 15:54 UTC ( [id://952766]=perlquestion: print w/replies, xml ) Need Help??

bcarroll has asked for the wisdom of the Perl Monks concerning the following question:

I often use perlapp (ActiveState Perl Dev Kit) to complile perl scripts and have often ran into the issue of misplacing the original source code and not being able to figure out how to get the source out of the compiled file.

Is there any way to print out the source code of the running script, from within the script? I assume this would have to occur at compile time...
It would be really neat if I could just use a module (like we do with warnings and strict) and pass a command-line argument to the script to have it dump the source code.

Does such a module exist, or is it even possible?

  • Comment on Print perl source code in compiled script...

Replies are listed 'Best First'.
Re: Print perl source code in compiled script...
by Old_Gray_Bear (Bishop) on Feb 09, 2012 at 16:47 UTC
    One Word -- git. (Or SVN, or CVS, or Perforce, even) Get into the Source Control habit now.

    ----
    I Go Back to Sleep, Now.

    OGB

      One word -- git.

      One more word: Bingo! (git is the answer to preventing this situation in the future.)

      And a few more words...

      How do I do that?

      Spend a few hours one evening reading Pro Git (free). Spend a few hours tinkering, reading man-pages, tinkering some more.

      Set up a local repo in one of your project's working directories. Set up a "bare" repo on a NAS you have mounted, or on a physically separate box to which you have SSH access. Learn how to commit, branch, merge, and push your local repo to the mounted or SSH-available one (for safe keeping).

      And if you really like learning it backwards and forwards, read Version Control with Git from O'Reilly.

      I recommend both Pro Git and Version Control with Git, and I would read them both in that order. The latter doesn't discuss Github at all, but is more thorough in just about every other way. The former is a gentler introduction, I think. Both are valuable.

      Then keep in mind the philosophy that anything worth working on is worth committing to version control.

      Now for a humorous quote:

      "Only wimps use tape backup: real men just upload their important stuff on ftp, and let the rest of the world mirror it ;)"
      -- Linus Torvalds, (1996-07-20). Post. linux.dev.kernel newsgroup. Google Groups. Retrieved on 2006-08-28.

      I think if Linus had created Git before coining this quote he would have said it more like this: "...real men just upload their important stuff onto an open source git repository, and let the rest of the world fork and clone it. ;)" And if he were a Perl enthusiast he may have mentioned CPAN too. :)

      Of course not everything belongs in an open source repo or on CPAN, but Git is great for private projects and local non-distributed version control too. At minimum setting up a bare repo and pushing local commits to it will ensure that you have two copies of the project's entire history; more if your repos themselves are part of an automated backup plan.

      Update: How could I forget merlyn's excellent Git talk? Follow the link for the video that includes Randal and his slides. It's just under two hours, and time well spent.


      Dave

      Where'd that bloody '++++++++' button go, now...

      Yeah. What Old_Gray_Bear said, in triplicate. If you're too lazy to do it manually (<cough> like a certain programmer whom I see in the mirror every morning...), configure your editor to automatically 'svn ci' what you're working on at every save, at least for your code.

      This has saved my bacon not just once, nor even twice. In various emergency and non-emergency situations, in a large variety of blowups, code rollbacks, other-programmer-caused problems, and in one case, a computer catching fire while I was at lunch (!), I would estimate the bacon-saving efficacy of that little hack at a couple of dozen.

      Don't get caught without it. :)

      -- 
      I hate storms, but calms undermine my spirits.
       -- Bernard Moitessier, "The Long Way"
Re: Print perl source code in compiled script...
by marto (Cardinal) on Feb 09, 2012 at 16:09 UTC

    First off, get in the habbit of making backups. "Misplacing" files isn't a good idea, as I'm sure you're finding out.

    The B::Deparse may be worth while investigating, I'd still say your time would be better spent implementing a working backup routine, rather relying on getting some form of your source code back via this method.

    If PerlApp works in a reasonably similar manner than other Perl packagers I'm sure you'll be able to get at least an obfuscated version of your source code back from packaged versions. See decompile perlapp 4.1 or Super Search for similar posts.

Re: Print perl source code in compiled script...
by LanX (Saint) on Feb 09, 2012 at 16:07 UTC
    You can use B::Deparse 's coderef2text() to reproduce code. Just wrap every file-scope into a main-sub to be able to deparse the top-level, too.

    But be aware that comments and constant-folding are of course lost.

    So maybe you should simply take care to keep the orignal source code!

    Another approach would be to attach the original code as a heredoc-string into your compilation!

    Maybe automated with a sourcefilter (which might be tricky when dealing with __DATA__ and __END__ tags)

    Something like that should then be added to your code:

    my $SOURCE_CODE = << '__END_OF_CODE__'; ... # my original code __END_OF_CODE__ sub DUMP_SOURCE { print $SOURCE_CODE; }

    Cheers Rolf

Re: Print perl source code in compiled script...
by educated_foo (Vicar) on Feb 09, 2012 at 16:00 UTC
Re: Print perl source code in compiled script...
by planetscape (Chancellor) on Feb 09, 2012 at 23:18 UTC
Re: Print perl source code in compiled script...
by bcarroll (Pilgrim) on May 08, 2015 at 12:48 UTC
    I agree, backing up and using a version control system is the best route for maintaining code, but often times for my purposes (one time use) that is overkill. Being able to extract the exact source code (non obfuscated, etc. ) from an executable is what I am looking for.

    And I think the answer is perlfilter.
    I threw together a module that implements what I am trying to achieve.
    Note: To ensure all of the sourcecode is captured, make sure use SourceDump; is the first line of the script file (or second line on *NIX). Any code that appears before use SourceDump; will not be captured

    Here is the SourceDump module:

    package SourceDump; #http://perldoc.perl.org/perlfilter.html use Filter::Util::Call; my $stdout = 1; # if true, prints sourcecode to STDOUT my $fileout = 1; # if true, writes sourcecode to FILE my $filename = 'SourceDump_'. time() .'.pl'; # sets name of file to + write to # import() is called automatically every time a module is included wit +h a use statement sub import { my ($type) = @_; my ($ref) = {}; filter_add(bless $ref); # create association between the filter obj +ect and the source stream } # filter() is called every time the Perl parser needs another line of +source to process sub filter { my ($self) = @_; my ($status); # If a line was available from the source stream, filter_read() re +turns a status value greater than zero and appends the line to $_ # A status value of zero indicates end-of-file, less than zero mea +ns an error. if ( ($status = filter_read()) > 0 ){ return(1) if $_ =~ /SourceDump/; # skip lines that include the + word "SourceDump". ***FUTURE USE*** &_stdout($_) if $stdout; &_fileout($_) if $fileout; } return($status); } ########################### # private methods ########################### sub _stdout { print $_; } sub _fileout { my $error = ""; open(my $FILE, '>>', $filename) or $error=$!; if ($error){ &_error('fileout', $!); return(undef); } print $FILE $_; close($FILE); } sub _error { my $source = shift; my $message = shift; print 'ERROR: ' . uc($source) . ", $message\n"; } 1;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://952766]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (2)
As of 2024-04-26 01:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found