Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

How to get at perl's options in a program

by mpersico (Monk)
on Nov 06, 2012 at 17:40 UTC ( [id://1002539]=perlquestion: print w/replies, xml ) Need Help??

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

In the command

perl -d:ptkdb -w myProg arg1 arg2

getting at arg1 arg2 is no issue. But in what data structure can I find out what perl options were presented (i.e.; the -d:ptkdb and the -w)?

Replies are listed 'Best First'.
Re: How to get at perl's options in a program
by kennethk (Abbot) on Nov 06, 2012 at 17:57 UTC
    If you want to do it on a *nix variant, you could use $$ in conjuction w/ ps, like:
    ~$ perl -e 'print `ps -o args -p $$`' COMMAND perl -e print `ps -o args -p $$`
    And the grab flags off that. Honestly, though, this smells of an XY Problem. What are you actually trying to accomplish? There are cleaner, cross-platform ways of testing for individual flags. And this method will miss flags in the hashbang.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      I'm writing a Tk interface to SVN for my own consumption because I like working a certain way. In particular, this is wrap of svn diff with each file in a tab. As I commit files and do other stuff on the files, I want to refresh the tabs to reflect the new file state. The easiest way to do that is to provide a button to re-exec the original command:

      my @reexec = [ $0, @ARGV ]; # when I press the refresh button: exec( @reexec )

      So far no big deal. But if I am debugging, I didn't run

      (pseudo) $0 @ARGV

      I ran

      (pseudo) perl -d:ptkdb $0 @ARGV

      To get around the issue, I do this:

      my @reexec = [ $0, @ARGV ]; if ( defined (&DB::DB ) ) { unshift @reexec, 'perl', '-d:ptkdb'; } # when I press the refresh button: exec( @reexec )

      but I was just wondering if there was a more generic way to read any perl option. I grok about the #! line args. I just figured that perl.exe would save that info some place. If there isn't, then there isn't. Thanks all. End of Thread.

        Yes, I often run into things where exec( $^X, ..., $0, @ARGV ) is a nice solution. Many times the "...," part doesn't matter. But increasingly, that has turned out to be a problem. And when it is a problem, it can be quite a hard problem.

        Thinking about it now, I think I'd use a shell script wrapper to solve it in a lot of cases, passing the full argument list via some back channel like an environment variable. Too bad bash doesn't just export $ENV{BASH_COMMAND} like it exports $ENV{_}. I guess I could arrange that as part of a DEBUG hook:

        trap 'export _CMD_LINE="$BASH_COMMAND"' DEBUG

        That worked quite well in a quick test. I wonder if I can even get bash to split that into arguments for me so I don't have to re-do bash's parsing logic (such as via Text::Shellwords, which might not be perfect for some complex cases). Maybe not since $BASH_COMMAND will include things like "> foo". Too bad $COMP_WORDS[@] is only available to programmable completion routines...

        But it would be a nice (and simple) enhancement to Perl for there to be some special variable like @{^ARGV} which would be a copy of the original argv that perl.exe got in its main(). It might also be nice to record how many of those were determined to be "options" when Perl finished going through them.

        - tye        

        A fairly reliable way to test if a module was loaded is to check for an associated entry in the Symbol Tables:

        #!/usr/bin/perl use strict; use warnings; use Data::Dumper; package Foo; 1; package main; print "Data::Dumper was ", defined $Data::{'Dumper::'} ? "loaded\n" : +"not loaded\n"; print "Foo was ", defined $::{'Foo::'} ? "loaded\n" : "not loaded\n"; print "Eata::Dumper was ", defined $Eata::{'Dumper::'} ? "loaded\n" : +"not loaded\n";

        This solution can be applied for any -M or -d. But, to the best of my understanding, the arguments themselves are lost to the ether.


        #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: How to get at perl's options in a program
by tobyink (Canon) on Nov 06, 2012 at 22:49 UTC

    Mwahahaha!!! Insane crap...

    { package Devel::PL_origargv; use 5.008; use Inline C => q{ int _argc () { return PL_origargc; } char* _argv (int x) { return PL_origargv[x - 1]; } }; sub get { return _argc unless wantarray; map _argv($_), 1 .. _argc; } } print "ARG: $_\n" for Devel::PL_origargv->get;

    Anyone think it's worth CPANning?

    Update: Devel::PL_origargv is now on CPAN. I kept the ugly name with weird capitalisation and punctuation, reasoning that if you have to think carefully to remember how to type the module name, then it will make you think carefully before using it.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      Sure, put it on CPAN. But also turn it into a patch against Perl.

      - tye        

      Thanks, tobyink++!So much of your stuff has either ended up in my code and/or taught me new things I never knew about Perl, I feel I owe you a *case* of beer. Seriously, if we ever meet at a YAPC or Hackathon, I will honor that!

      While your module doesn't *quite* solve the problem I came here to research, it points me in the right direction. I've spent some time today groveling in the perl source and found a few more useful variables like that, for example PL_origenviron

      I'm working on a means of bootstrapping perl applications using a new perl installation on systems stuck with an old perl, but without needing to run or install external CPAN modules as root. In trying to make this as simple as possible, I have code that, if run with too old a version of perl, attempts to find a new-enough one, and re-execs the original command using the found perl. (Additionally, it will update a perl-version-specific local::lib using cpanm if one of {Makefile,Build}.PL are present, and add it to @INC). Unfortunately, it's a nasty combination of bash and perl, and I'd *love* to dispense with the bash all together.

      Now, I know this sort of thing can be "solved" using perlbrew, but unfortunately perlbrew has not worked out very well for the users & devs I am supporting. Also, they dislike having to keep a new installation of perl around for every project. (several are new to perl, and are giving me their time to help me deliver several projects for their groups. I feel I owe it to them to make using and hacking on on my code as comfortable as possible... so far, it's working - two have now expressed that they never knew Perl could be such a nice language to use!)

      Once I feel like I have good general solution, I will release whatever I can :)

      FWIW, you should not use Inline inside a module, you end up with

      ./Devel-PL_origargv-0.003/_Inline/lib/auto/Devel/PL_origargv_a77c/PL_o +rigargv_a77c.dll
      which doesn't get installed, and and an empty
      ./Devel-PL_origargv-0.003/blib/lib/auto/Devel/PL_origargv/.exists
      and then every time someone uses the module, in the current directory, an _Inline/lib/auto/Devel/PL_origargv_a77c/PL_origargv_a77c.dll is built, every single time, instead of once during installation

        It's not built every single time. It's only rebuilt if it's missing or if there have been modifications to the .pm file since the last build. If you don't like it being built in the current working directory, then create a ~/.Inline directory.

        I'd happily accept a patch to XSify the module, but I'm not going to write that myself. It seems more effort than would be deserved by this silly little module.

        use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
Re: How to get at perl's options in a program
by Anonymous Monk on Nov 06, 2012 at 17:48 UTC
Re: How to get at perl's options in a program
by Anonymous Monk on Nov 06, 2012 at 17:50 UTC
    FWIW, -w turns on $^W, and -d:ptkdb is "use Devel::ptkdb; "

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (4)
As of 2024-04-25 21:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found