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.
| [reply] [d/l] |
|
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. | [reply] [d/l] [select] |
|
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.
| [reply] [d/l] [select] |
|
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.
| [reply] [d/l] [select] |
|
Re: How to get at perl's options in a program
by tobyink (Canon) on Nov 06, 2012 at 22:49 UTC
|
{
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'
| [reply] [d/l] |
|
| [reply] |
|
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 :)
| [reply] |
|
./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 | [reply] [d/l] [select] |
|
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
| [reply] |
|
|
|
|
Re: How to get at perl's options in a program
by Anonymous Monk on Nov 06, 2012 at 17:48 UTC
|
| [reply] |
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; " | [reply] |