[18641] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 809 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue May 1 09:07:31 2001

Date: Tue, 1 May 2001 06:05:09 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Message-Id: <988722309-v10-i809@ruby.oce.orst.edu>
Content-Type: text

Perl-Users Digest           Tue, 1 May 2001     Volume: 10 Number: 809

Today's topics:
        Capturing the output of perl -c myfile.pl <jfreeman@tassie.net.au>
        CGI/Perl scripts not readable ! (Tony Van der Voort)
    Re: Chicago Perl Consultants Needed <webmaster@webdragon.unmunge.net>
        Closures and hash tables <e_bachmann@hotmail.com>
    Re: Closures and hash tables (Damian James)
        Getting IP address and not a proxy one? <paul.brown@ukinternetsites.com>
    Re: Getting IP address and not a proxy one? (Damian James)
        glob questions <"relaxedrob@optushome.com.au">
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Tue, 01 May 2001 21:31:35 +1000
From: Jfreeman <jfreeman@tassie.net.au>
Subject: Capturing the output of perl -c myfile.pl
Message-Id: <3AEE9E97.860F9744@tassie.net.au>

Hi  All

I have a perl parsing script that will strip the comments off 100% of the perl
in the standard distribution (about 120,000 lines in ~600 scripts). For details
on this program see the Hacker Challenge thread.

A central part of this script is a compile checker. Because a parser that strips
comments and concatenates a script may potentially break a script if it makes a
parsing error the simple approach taken in this script is as follows:

1 Compile check target script.
2 Write and verify a backup.
3 Process the script overwriting the original.
4 Repeat the compile check on the processed target script, and if it fails
regenerate the original script from the backup.

Using this approach ensures that the strip-comment parsing does not break
scripts. Because it has proven impossible to capture the output from perl -c
here is what I currently use:

sub compile {

    no strict;
    no warnings;
    my $path = shift;
    print"Compile check $path\n";
    # this next line puts the lines of the test script into @check_file
    my @check_file = &get_script($path, 1);
    my $perl = 'goto EXIT_EVAL_CODE_AFTER_COMILATION_BUT_BEFORE_RUNNING_IT;';
    for (@check_file) {$perl .= $_;}
    # remove use warnings from test script in case of duplicate sub/var defs
    $perl =~ s/use\s+warnings\s*;//g;
    # stripcomments.pl can't eval itself without destroying namespace
  return 0 if $perl =~ m/package Stripcomments/;
    # don't eval bootstrap containing scripts as they hang system
  return "Sorry, can't eval bootstraps without problems!" if $perl =~
m/bootstrap/;
    # kill off autoload subs as they hang system
    $perl =~ s/sub\s+AUTOLOAD/sub AUTOLOAD {} sub KILLED_OFF_OLD_AUTOLOAD/g;
    # we now eval our script which compiles then effectively exits immediately
    # after comilation because the first statement it runs is the line we added:

    # goto EXIT_EVAL_CODE_AFTER_COMILATION_BUT_BEFORE_RUNNING_IT;
    eval "$perl";

EXIT_EVAL_CODE_AFTER_COMILATION_BUT_BEFORE_RUNNING_IT:
    ($@) ? print "Compile ckeck failed!\n" : print "Compile check OK\n";
    return ($@) ? $@ : 0;
}

I am not happy with my current compile checker for several reasons. Although it
basically works it seems an ugly, memory hogging solution which could easily be
solved if only I could capture the output of `perl -c testscript.pl` into a
variable or even a file. An added disadvantage of the eval method used is that
some valid scripts fail under an eval and some need to be excluded for anti
crash purposes.

When executed within a script using backticks or an open the output of perl -c
seems hardwired to STDOUT, at least under win32. All the redirection suggestions
in the FAQ8:"How can I capture STDERR from an external command?" fail to capture
or deflect this output from STDOUT.

Here is a short script with its output that demonstrates the problem I have
with  capturing output from perl -c

#!usr/bin/perl

print "Hello World!\n";

`perl -c test.pl`;

$output = `perl -c test.pl`;
print "Command 1 returned:$output\n";

$pid = open(PH, "perl -c test.pl|");
$output = <PH>;
print "Command 2 returned:$output\n";

print "\nRedirecting STDOUT to ./logfile.txt\n";
open(STDOUT, ">./logfile.txt");

print "Post redirect Hello World!\n";

`perl -c test.pl`;

$output = `perl -c test.pl`;
print "Post redirect Command 1 returned:$output\n";

$pid = open(PH, "perl -c test.pl|");
$output = <PH>;
print "Post redirect Command 2 returned:$output\n";

__END__


Running this script (called test.pl) returns:

C:\>perl test.pl
Hello World!
test.pl syntax OK
test.pl syntax OK
Command 1 returned:
test.pl syntax OK
Command 2 returned:

Redirecting STDOUT to ./logfile.txt
test.pl syntax OK
test.pl syntax OK
test.pl syntax OK

C:\>type logfile.txt
Post redirect Hello World!
Post redirect Command 1 returned:
Post redirect Command 2 returned:

C:\>


As you can see the output of perl -c seems hard-wired into STDOUT. The
redirection of STDOUT makes no difference, only redirecting everyting else to
the file! $| = 1; to flush buffers makes no difference.

I don't understand this behavior. If I have a file 'hello_world.pl' that just
prints Hello World! to STDOUT:

C:\>perl hello_world.pl
Hello World!
C:\>

then when I run this program (called test.pl of course!):

#!usr/bin/perl

$output = `perl hello_world.pl`;
print "Command 1 returned:$output";

$pid = open(PH, "perl hello_world.pl|");
$output = <PH>;
print "Command 2 returned:$output";

__END__


It captures the output of hello_world.pl and generates the expected output:

C:\>perl test.pl
Command 1 returned:Hello World
Command 2 returned:Hello World

C:\>


I can generate a working kludge in a different way by adding the line:

print "Syntax OK"; exit;

to the beginning of the test file then running it and capturing the output. This
only returns "Syntax OK" if it actually runs but once again the syntax error
output does not capture. This script is called compile.pl

#!usr/bin/perl

&compile($ARGV[0]);

sub compile {

    my $path = shift;
    my $temp = './temp_file.pl';
    my $test;
    print"Compile check $path\n";
    my @check_file = &get_script($path, 1);
    open (TEMP, ">", $temp) || die "Unable to open $temp:$!\n";
    print TEMP "print \"Syntax OK\";exit;\n";
    for (@check_file) {chomp; print TEMP "$_\n";}
    eval '$test = `perl $temp`';
    print "Found in \$\@: $@\n";
    print "Found in \$test: $test\n";
    unlink $temp || die "Unable to unlink $temp:$!\n";
    if($test =~ m/Syntax OK/) {
        print "Compile ckeck OK!\n";
        return 0;
    } else {
        print "Compile check failed\n";
        return 1;
    }
}

sub get_script {

    my $path = shift;
    open (FILE, "<", "$path") or die "Unable to open input file $path $!\n";
    my @file = <FILE>;
    close FILE;
  return @file;
}

__END__


If you run this script on broken.pl, a perl file containing syntax errors.

C:|>perl compile.pl broken.pl
Compile check broken.pl
Missing right curly or square bracket at ./temp_file.pl line 2, at end of line
syntax error at ./temp_file.pl line 2, at EOF
Execution of ./temp_file.pl aborted due to compilation errors.
Found in $@:
Found in $test:
Compile check failed

C:\>

If you run it on some valid perl in the file good.pl

C>perl test.pl good.pl
Compile check broken.pl
Found in $@:
Found in $test: Syntax OK
Compile ckeck OK!

C:\>



This second method is cleaner than the eval I am using but does not capture the
error message.

Am I missing something embarrassingly basic?
Is this a platform related problem?
Can you help?


Cheers

James






------------------------------

Date: Tue, 01 May 2001 12:54:46 GMT
From: tvdv@advalvas.be (Tony Van der Voort)
Subject: CGI/Perl scripts not readable !
Message-Id: <3aeeb164.13858992@news.skynet.be>

I'm hosting webspace and on that space there are a lot of CGI/Perl
scripts pre-installed. But, when I download them on my harddisk and
want to look to the code, i have only unreadable rubbish. 

What's the reason of that ? Is there a way to compile CGI/Perl code
before uploading to the server, so that other people that comes on
that server cannot look in the original code ?


------------------------------

Date: 1 May 2001 09:18:43 GMT
From: "Scott R. Godin" <webmaster@webdragon.unmunge.net>
Subject: Re: Chicago Perl Consultants Needed
Message-Id: <9clv1j$t7p$0@216.155.32.176>

In article <slrn9erg2c.hej.tadmc@tadmc26.august.net>,
 tadmc@augustmail.com (Tad McClellan) wrote:

 | >It's responses like this that are the root of the problem...
 | 
 | 
 | Who asked you to stick your pro_tuber_ance in?

Cogito Ergo Spud. I think, therefore I Yam.

-- 
unmunge e-mail here:
#!perl -w
print map {chr(ord($_)-3)} split //, "zhepdvwhuCzhegudjrq1qhw"; 
# ( damn spammers. *shakes fist* take a hint. =:P )


------------------------------

Date: Tue, 1 May 2001 13:16:19 +0200
From: "Erik Bachmann" <e_bachmann@hotmail.com>
Subject: Closures and hash tables
Message-Id: <8WwH6.139$Qj7.8238@news.get2net.dk>

Closures and hash tables

I'm trying to implement a call to a subrouting in a hash table.

The examples in the various O'Reiley Perl books are quite simple, but I
can't figure out how to dereference the function in the example below.

Can anyone help?

Regards

Erik Bachmann

#---8<----- SNIP ----->8---
#!/usr/bin/perl

my $fieldcode="001";
my $subfield_tag= "a" ;
my $fields="";

$subfield = "123";

sub myfunc($) {
 my ($str) = @_ ;
 print STDERR "\nHello [$str]\n" ;
}

%MAIN::format = ( "001" => { "a" => {  "func" => \&myfunc(
$subfield ) } } );

#===============================================================

$subfield = "world" ;

if ( $MAIN::format{$fieldcode}{$subfield_tag}{func} )
{
 print "Function found\n" ;
 print STDERR ref $MAIN::format{$fieldcode}{$subfield_tag}{func} ;
 $MAIN::format{$fieldcode}{$subfield_tag}{func} ;
 print "Done\n" ;
}
else
{
 print "Function NOT found\n" ;
}

__DATA__

Current output:

 Hello [123]
 Function found
 SCALARDone

Expected output:

 Function found
 SCALAR
 Hello [world]
 Done
#---8<----- SNIP ----->8---





------------------------------

Date: 1 May 2001 11:47:15 GMT
From: damian@qimr.edu.au (Damian James)
Subject: Re: Closures and hash tables
Message-Id: <slrn9et8ee.7vm.damian@puma.qimr.edu.au>

Erik Bachmann chose Tue, 1 May 2001 13:16:19 +0200 to say this:
>...
>The examples in the various O'Reiley Perl books are quite simple, but I
>can't figure out how to dereference the function in the example below.
>...
> $MAIN::format{$fieldcode}{$subfield_tag}{func} ;

$MAIN::format{$fieldcode}{$subfield_tag}{func}->();

	or 

&{$MAIN::format{$fieldcode}{$subfield_tag}{func}};

See perldoc perlref.

You should familiarise yourself with the online docs.

HTH,

Cheers,
Damian
-- 
@:=grep!($;+=m!$/|#!),split//,<DATA>;@;=0..$#:;while(@;){for($;=@;;--$;;)
{@;[$;,$:]=@;[$:,$;]if($:=rand$;+$|)!=$;}push@|,shift@;if$;[0]==@|;select
$,,$,,$,,1/80;print qq x\bxx((@;+@|)*$|++),@:[@|,@;],!@;&&$/} __END__
Just another Perl Hacker # rev 3.1 -- a JAPH in progress, I guess...


------------------------------

Date: Tue, 1 May 2001 12:43:28 +0100
From: "Paul Brown" <paul.brown@ukinternetsites.com>
Subject: Getting IP address and not a proxy one?
Message-Id: <xjxH6.20696$PP3.1583072@nnrp3.clara.net>

Hi,

Just a quick question, for a login system I have wrote it logs the IP
address of the visitor.  At the moment I am using the env -
$ENV{REMOTE_ADDR} works great.  However some visitors have told me it logs
the wrong IP address for them.

After some digging I found it was done to that visitor using a proxy server
or a have a funny network setup.  So my script logs the proxy server or the
network IP address - and not the users IP.

Is there a modual or another env which returns the users actually IP address
and not the network/proxy one?

Any ideas?  Thanks,

Paul






------------------------------

Date: 1 May 2001 12:04:04 GMT
From: damian@qimr.edu.au (Damian James)
Subject: Re: Getting IP address and not a proxy one?
Message-Id: <slrn9et9du.7vm.damian@puma.qimr.edu.au>

Paul Brown chose Tue, 1 May 2001 12:43:28 +0100 to say this:
>...
>After some digging I found it was done to that visitor using a proxy server
>or a have a funny network setup.  So my script logs the proxy server or the
>network IP address - and not the users IP.
>
>Is there a modual or another env which returns the users actually IP address
>and not the network/proxy one?
>

No, this is not even possible. The reasons have nothing to do with Perl. 

[OT]
People run proxy servers for a variety of reasons, often because the hosts
users run browsers on don't even have valid internet addresses (which is
what you might be referring to as a 'funny network setup'). 

HTH, sorry it probably doesn't

Cheers,
Damian
-- 
@:=grep!($;+=m!$/|#!),split//,<DATA>;@;=0..$#:;while(@;){for($;=@;;--$;;)
{@;[$;,$:]=@;[$:,$;]if($:=rand$;+$|)!=$;}push@|,shift@;if$;[0]==@|;select
$,,$,,$,,1/80;print qq x\bxx((@;+@|)*$|++),@:[@|,@;],!@;&&$/} __END__
Just another Perl Hacker # rev 3.1 -- a JAPH in progress, I guess...


------------------------------

Date: Tue, 01 May 2001 12:38:09 GMT
From: "Rob" <"relaxedrob@optushome.com.au">
Subject: glob questions
Message-Id: <R6yH6.1298$76.5015@news1.rdc1.nsw.optushome.com.au>

Howdy all!
I have two questions to do with the glob function and an error I am getting
in my code that I cannot work out.

QUESTION ONE

Here is a snippet of my code.

# ....... start snippet

# variable declarations
my %file_descriptor;
my %file_descriptors;
my $fd_key;
my $fd;
my @files;
my $file;

# .......

%file_descriptors = (
   "binary"    => "/usr/bin/perl",
   "text"      => "/users2/gasux/rmbra1/bin/fat.tmp",
   "directory" => "/users2/gasux/rmbra1/bin",
); # end hash assignment

# .......

# option 1 - glob from hash
@files = glob ("$file_descriptors {directory}/*");     # line 78

# ....... end snippet

The error I get is this:
~/bin >perl file_test2.pl
Global symbol "$file_descriptors" requires explicit package name at
file_test2.pl line 78.
BEGIN not safe after errors--compilation aborted at file_test2.pl line 78.
~/bin >

Now when I shift it over to this everything is fine and I get my list of
files and directories:

# option 2 - glob indirectly from hash
$file_descriptor = $file_descriptors {directory};
@files = glob ("$file_descriptor/*");

QUESTION TWO
Why does glob (path\*) return to me a list of all directories and files in
the directory *except* for . and ..?

Thanks!
Rob




------------------------------

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>


Administrivia:

The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc.  For subscription or unsubscription requests, send
the single line:

	subscribe perl-users
or:
	unsubscribe perl-users

to almanac@ruby.oce.orst.edu.  

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.

For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V10 Issue 809
**************************************


home help back first fref pref prev next nref lref last post