K
Kiss Gabor
I have need a code snippet those input is a text of a perl subroutine
(e.g. coming from a file) and the output of list of global variables
used by the sub.
So far I created something like this:
-------------8<-------------------8<------------------
# $code holds the source of subroutine. E.g.:
$code = q{ sub { my $aaa = $bbb + $ccc; return $aaa; } };
my %vars;
open(PARSER,q{perl -c -e 'use strict; }.$code.q{' 2>&1 |}) or die;
while (<PARSER>) {
next unless /Global symbol "\$(\w+)" requires explicit package name at/;
$vars{$1}++;
}
close PARSER;
my $varlist;
foreach (keys %vars) {
$varlist .= qq{our \$$_; };
}
# In the second pass globals do not cause error.
# Let's see if syntax is correct otherwise.
open(PARSER,q{perl -c -e 'use strict; }.$varlist.$code.q{' 2>&1 |}) or die;
while (<PARSER>) {
# check other errors or '-e syntax OK' message
}
close PARSER;
# Global variables are keys of %vars (I.e. 'bbb' and 'ccc')
-------------8<-------------------------8<------------------
However this is not an elegant solution. I wonder if there is any way
to omit one or both fork+exec.
Any hints will be appreciated.
Gabor
(e.g. coming from a file) and the output of list of global variables
used by the sub.
So far I created something like this:
-------------8<-------------------8<------------------
# $code holds the source of subroutine. E.g.:
$code = q{ sub { my $aaa = $bbb + $ccc; return $aaa; } };
my %vars;
open(PARSER,q{perl -c -e 'use strict; }.$code.q{' 2>&1 |}) or die;
while (<PARSER>) {
next unless /Global symbol "\$(\w+)" requires explicit package name at/;
$vars{$1}++;
}
close PARSER;
my $varlist;
foreach (keys %vars) {
$varlist .= qq{our \$$_; };
}
# In the second pass globals do not cause error.
# Let's see if syntax is correct otherwise.
open(PARSER,q{perl -c -e 'use strict; }.$varlist.$code.q{' 2>&1 |}) or die;
while (<PARSER>) {
# check other errors or '-e syntax OK' message
}
close PARSER;
# Global variables are keys of %vars (I.e. 'bbb' and 'ccc')
-------------8<-------------------------8<------------------
However this is not an elegant solution. I wonder if there is any way
to omit one or both fork+exec.
Any hints will be appreciated.
Gabor