http://www.perlmonks.org?node_id=1002568


in reply to Re: How to get at perl's options in a program
in thread How to get at perl's options in a program

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.

Replies are listed 'Best First'.
Re^3: How to get at perl's options in a program (exec)
by tye (Sage) on Nov 06, 2012 at 21:57 UTC

    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        

Re^3: How to get at perl's options in a program
by kennethk (Abbot) on Nov 06, 2012 at 21:25 UTC
    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.

      That's actually a pretty flaky technique.

      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"; # Here's a false positive! # "Data::Dumper" was loaded, and that makes it look like # "Data" has also been loaded... # print "Data was ", defined $::{'Data::'} ? "loaded\n" : "not loaded\n" +; # Here's another false positive! # When we checked if "Eata::Dumper" was loaded, # autovivification makes it look like "Eata" was loaded. # print "Eata was ", defined $::{'Eata::'} ? "loaded\n" : "not loaded\n" +;

      It's much better to check for the existence of the actual functions/methods you wish to use:

      my $Dumper = UNIVERSAL::can('Data::Dumper', 'can') && 'Data::Dumper'->can('Dumper'); print $Dumper->($hashref) if defined $Dumper;
      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'