[comp.lang.perl] "Out of memory!"?

poage@sunny.ucdavis.edu (Tom Poage) (07/14/90)

I'm tinkering with redirecting stdout and stderr
to files and then looking at the results.  However,
one variant gives me "Out of memory!" (Sun 3/150, 4.0.3).

#START
open(SAVEOUT, ">&STDOUT");	# Save file descriptors.
open(SAVEERR, ">&STDERR");
open(STDOUT, ">$OFILE");	# Output file.
open(STDERR, "+>$EFILE");	# Error file.

#system('/bin/MyProgram', @COMMANDS);
print STDERR "multiple\nline\nSQL:\nstuff\n"; #DEBUG:simulate error.

close(STDOUT);
open(STDOUT, ">&SAVEOUT");
#close(STDERR);
#open(STDERR, ">&SAVEERR");

open(PRGOUT, $OFILE);		# Let's look at the output.
#open(EFILE, $EFILE);		# Let's look for errors.
seek(STDERR, 0, 0);		# We'll just rewind the error file instead.

if (@errs = grep( do{/^SQL:/ ? undef : s/^/\t/o;}, <STDERR>)) {
	print "Error message(s):\n", @errs; #DEBUG
} else {
	print while <PRGOUT>; #DEBUG
}
#END

Now, what I want to do is grub through what was produced to stderr,
remove purely informational stuff (/^SQL/) and prepend a tab to all
the real errors (a format, sorta).

This works properly

	if (@errs = grep(s/^/\t/, grep(!/^SQL:/, <STDERR>))) {
	....

So does this

	@messages = <STDERR>;
	if (@errs = grep( do{/^SQL:/ ? undef : s/^/\t/o;}, @messages)) {
	....

But this

	if (@errs = grep( do{/^SQL:/ ? undef : s/^/\t/o;}, <STDERR>)) {
	....

produces "Out of memory!".  Did I do something to deserve this?
Anyone care to comment?  Tom.
-- 
Tom Poage, Clinical Engineering
Universiy of California, Davis, Medical Center, Sacramento, CA
poage@sunny.ucdavis.edu  {...,ucbvax,uunet}!ucdavis!sunny!poage

poage@sunny.ucdavis.edu (Tom Poage) (07/14/90)

In article <482@sunny.ucdavis.edu> poage@sunny.ucdavis.edu (I) write:
...

This gives "Out of memory!"

>if (@errs = grep( do{/^SQL:/ ? undef : s/^/\t/o;}, <STDERR>)) {...

This works

>	if (@errs = grep(s/^/\t/, grep(!/^SQL:/, <STDERR>))) {...

So does this

>	@messages = <STDERR>;
>	if (@errs = grep( do{/^SQL:/ ? undef : s/^/\t/o;}, @messages)) {...

Doing some additional poking around,

	open(JUNK, "junkfile");
	@x=grep(do{!/^SQL:/?s/^/\t/:undef;},<JUNK>);

dumps core.  Somehow the <JUNK> isn't expanded to a list: at
the lowest level, perl expects a struct string *, but actually
gets a stuct _iobuf * as the second argument to grep.

So why is <STDERR> expanded to a list in the inner grep of

	if (@errs = grep(s/^/\t/, grep(!/^SQL:/, <STDERR>))) {...

where
	if (@errs = grep( do{/^SQL:/ ? undef : s/^/\t/o;}, <STDERR>)) {...

is not?
-- 
Tom Poage, Clinical Engineering
Universiy of California, Davis, Medical Center, Sacramento, CA
poage@sunny.ucdavis.edu  {...,ucbvax,uunet}!ucdavis!sunny!poage

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (07/17/90)

In article <484@sunny.ucdavis.edu> poage@sunny.ucdavis.edu (Tom Poage) writes:
: So why is <STDERR> expanded to a list in the inner grep of
: 
: 	if (@errs = grep(s/^/\t/, grep(!/^SQL:/, <STDERR>))) {...
: 
: where
: 	if (@errs = grep( do{/^SQL:/ ? undef : s/^/\t/o;}, <STDERR>)) {...
: 
: is not?

The manual currently says, under grep:

             Note that, since $_ is a reference into the array
             value, it can be used to modify the elements of the
             array.  While this is useful and supported, it can
             cause bizarre results if the LIST contains literal
             values.

That last bit should probably say

             ...cause bizarre results if the LIST is not a named array.

What you are doing, I believe, is modifying temporary stack values that
are being freed when the grep exits.  Don't do that.  It's erroneous,
in language-lawyerese.

Larry