[24637] in Perl-Users-Digest
Perl-Users Digest, Issue: 6801 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Aug 3 12:36:13 2004
Date: Tue, 3 Aug 2004 09:35:38 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Tue, 3 Aug 2004 Volume: 10 Number: 6801
Today's topics:
Brute-Force-like array <susikaufmann2003@hotmail.com>
Re: Brute-Force-like array <mritty@gmail.com>
Re: Brute-Force-like array <susikaufmann2003@hotmail.com>
Re: Brute-Force-like array <mritty@gmail.com>
Re: Brute-Force-like array <lallip@barbara.cs.rpi.edu>
Re: Brute-Force-like array 510046470588-0001@t-online.de
Re: Brute-Force-like array <bowsayge@nomail.afraid.org>
Re: Brute-Force-like array (Anno Siegel)
Re: Brute-Force-like array <bowsayge@nomail.afraid.org>
capture/supress stdout from perl module called from cgi <project2501@project2501.cor>
Re: capture/supress stdout from perl module called from <ebohlman@omsdev.com>
Re: capture/supress stdout from perl module called from (Anno Siegel)
Re: capture/supress stdout from perl module called from <usenet@vyznev.invalid>
Carp -- shortmess and longmess <hakonrk@fys.uio.no>
Re: Carp -- shortmess and longmess <abigail@abigail.nl>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Thu, 29 Jul 2004 18:52:30 +0200
From: "Susanne" <susikaufmann2003@hotmail.com>
Subject: Brute-Force-like array
Message-Id: <ceba0e$smm$04$1@news.t-online.com>
Hello,
i want to write a subroutine, that creates something like an
"brute-force-array" (i don't know a better name for this).
It should work like this: the subroutine gets a parameter e.g. "3".
Then the subroutine returns an Array with a,bc....aa,ab,ac....aaa,aab.....
Does someone have an idea how to solve this?
Susanne
------------------------------
Date: Thu, 29 Jul 2004 13:24:17 -0400
From: Paul Lalli <mritty@gmail.com>
Subject: Re: Brute-Force-like array
Message-Id: <20040729132036.E3404@barbara.cs.rpi.edu>
On Thu, 29 Jul 2004, Susanne wrote:
> Hello,
>
> i want to write a subroutine, that creates something like an
> "brute-force-array" (i don't know a better name for this).
Coming up with one would help define your problem.
> It should work like this: the subroutine gets a parameter e.g. "3".
>
> Then the subroutine returns an Array with a,bc....aa,ab,ac....aaa,aab.....
>
> Does someone have an idea how to solve this?
Solve what? You have not at all defined your problem statement. You've
shown input, you've shown something resembling output, but you haven't
come close to telling us how one relates to the other.
What does '3' have to do with what you showed us? Is it the number of
letters used in the resulting data? Is it the maximum length of the
string in the resulting data? Is it the maxium length of a subset in the
resulting data?
And what exactly *is* the output? A series of strings? A collection of
arrays of strings?
You need to be a lot more precise with what you're trying to do before
you'll get any helpful advise.
While you're at it, check out the FAQ answer to "How do I permute N
elements of a list?" to see if that gives you any ideas.
perldoc -q permute
Paul Lalli
------------------------------
Date: Thu, 29 Jul 2004 21:13:34 +0200
From: "Susanne" <susikaufmann2003@hotmail.com>
Subject: Re: Brute-Force-like array
Message-Id: <cebi8v$s38$03$1@news.t-online.com>
ok...sorry:
i have got this:
my @test = (a,b,c);
my $length = 4;
foreach $letter(@test){
for (my $i =0; $i<=3; $i++){
$out = $letter.$test[$i];
push (my @array, $out);
}
}
return @array;
but this way i only got [a, aa, ab, ac, ad, ae....] but nothing over two
letters. but i also want the values "aaa, aab, aac, aba...." in my array.
The length should be given bei the $length-String.
I hope it's more clear now.
Susanne
------------------------------
Date: Thu, 29 Jul 2004 15:33:56 -0400
From: Paul Lalli <mritty@gmail.com>
Subject: Re: Brute-Force-like array
Message-Id: <20040729152217.M3404@barbara.cs.rpi.edu>
On Thu, 29 Jul 2004, Susanne wrote:
> ok...sorry:
>
> i have got this:
>
> my @test = (a,b,c);
> my $length = 4;
>
> foreach $letter(@test){
> for (my $i =0; $i<=3; $i++){
> $out = $letter.$test[$i];
> push (my @array, $out);
> }
> }
> return @array;
>
No you don't. This produces no output, as @array is completely empty when
you leave the for loops. Post real code.
>
> but this way i only got [a, aa, ab, ac, ad, ae....]
No you didn't. There's no way to produce ad or ae with that code. Post
real results.
> but nothing over two
> letters. but i also want the values "aaa, aab, aac, aba...." in my array.
> The length should be given bei the $length-String.
1) I ask again - the length of what? The maximum length of the string in
the resulting array? Or the maximum size of the array itself?
2) You're not using $length anywhere after declaring it. How are you
expecting it to work?
> I hope it's more clear now.
Mildly. Did you look at the "permute" documentation I posted earlier? It
should be possible to do this fairly easily using the List::Permutor
module it refers to...
Paul Lalli
P.S. When replying, please include the text you're replying to, above
your reply. Thanks.
------------------------------
Date: Thu, 29 Jul 2004 16:19:06 -0400
From: Paul Lalli <lallip@barbara.cs.rpi.edu>
Subject: Re: Brute-Force-like array
Message-Id: <20040729161626.U3404@barbara.cs.rpi.edu>
On Thu, 29 Jul 2004, Paul Lalli wrote:
> > ok...sorry:
> >
> > i have got this:
> >
> > my @test = (a,b,c);
> > my $length = 4;
> >
> > foreach $letter(@test){
> > for (my $i =0; $i<=3; $i++){
> > $out = $letter.$test[$i];
> > push (my @array, $out);
> > }
> > }
> > return @array;
> >
> > I hope it's more clear now.
>
> Mildly. Did you look at the "permute" documentation I posted earlier? It
> should be possible to do this fairly easily using the List::Permutor
> module it refers to...
I got bored while waiting for some clients at work... This is my first
attempt. It's not at all efficient, and I'm sure others here would be
able to make it much cleaner. But it does produce (what I believe to be)
your desired output:
#!/usr/bin/env perl
use strict;
use warnings;
use List::Permutor;
my @data = qw/a b c d/;
my %results; #where we'll store each string we find
sub perm {
return unless @_; #base case for recursion is just to exit
my $perm = new List::Permutor @_;
while (my @tempresults = $perm->next){
#join each subset into a string, and record it
$results{join '', @tempresults}++;
}
#remove one element at a time from data, and permute the result
for my $i (0 .. $#_){
my @temp = @_;
splice @temp, $i, 1;
perm(@temp);
}
}
#start everything off
perm (@data);
#Get one copy each of each string found.
my @results = sort keys %results;
print "@results\n";
__END__
a ab abc abcd abd abdc ac acb acbd acd acdb ad adb adbc adc adcb b ba bac
bacd bad badc bc bca bcad bcd bcda bd bda bdac bdc bdca c ca cab cabd cad
cadb cb cba cbad cbd cbda cd cda cdab cdb cdba d da dab dabc dac dacb db
dba dbac dbc dbca dc dca dcab dcb dcba
------------------------------
Date: 29 Jul 2004 22:21:32 +0200
From: 510046470588-0001@t-online.de
Subject: Re: Brute-Force-like array
Message-Id: <87llh236pf.fsf@debian.i-did-not-set--mail-host-address--so-shoot-me>
"Susanne" <susikaufmann2003@hotmail.com> writes:
> ok...sorry:
>
> i have got this:
>
> my @test = (a,b,c);
> my $length = 4;
>
> foreach $letter(@test){
> for (my $i =0; $i<=3; $i++){
> $out = $letter.$test[$i];
> push (my @array, $out);
> }
> }
> return @array;
>
>
> but this way i only got [a, aa, ab, ac, ad, ae....] but nothing over two
> letters. but i also want the values "aaa, aab, aac, aba...." in my array.
> The length should be given bei the $length-String.
>
sub brute_array {
my $length = shift;
my $test = shift;
my $combo = sub {
my ($a,$b) = @_;
my @r = ();
for (@$a) {
my $s = $_;
for (@$b) {
push (@r, $s . $_);
};
};
return \@r;
};
my $s = [""];
my @r = ();
for (1 .. $length) {
$s = &$combo ($s, $test);
push (@r, @$s);
};
return \@r;
};
Klaus Schilling
------------------------------
Date: Fri, 30 Jul 2004 08:25:06 GMT
From: bowsayge <bowsayge@nomail.afraid.org>
Subject: Re: Brute-Force-like array
Message-Id: <CBnOc.2341$Jp6.958@newsread3.news.atl.earthlink.net>
Susanne said to us:
[...]
> but this way i only got [a, aa, ab, ac, ad, ae....] but nothing over two
> letters.
[...]
Is something like this what you want to do?
#!/usr/bin/perl
use strict;
use warnings;
my ($length, @test) = (4, 'a'..'c');
sub func {
my ($bref, $depth) = (@_);
if ($depth >= $length) {
print "$bref\n";
return;
}
foreach my $var (@test) {
func("$bref$var", $depth + 1);
}
}
func '', 0;
The length of the string is always 4 chars with this program.
Bowsayge doesn't know how to include the shorter strings such
as "aa, ab, ... abc". Perhaps someone can modify the program
to get those too?
HTH
--
bowsayge
------------------------------
Date: 30 Jul 2004 09:52:53 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Brute-Force-like array
Message-Id: <ced5pl$dsn$1@mamenchi.zrz.TU-Berlin.DE>
bowsayge <bowsayge@nomail.afraid.org> wrote in comp.lang.perl.misc:
> Susanne said to us:
>
> [...]
> > but this way i only got [a, aa, ab, ac, ad, ae....] but nothing over two
> > letters.
> [...]
>
> Is something like this what you want to do?
>
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> my ($length, @test) = (4, 'a'..'c');
>
> sub func {
> my ($bref, $depth) = (@_);
> if ($depth >= $length) {
> print "$bref\n";
> return;
> }
> foreach my $var (@test) {
> func("$bref$var", $depth + 1);
> }
> }
>
> func '', 0;
>
>
> The length of the string is always 4 chars with this program.
> Bowsayge doesn't know how to include the shorter strings such
> as "aa, ab, ... abc". Perhaps someone can modify the program
> to get those too?
Very easy. Just call the function with different values in the
global $length:
for ( 1 .. 4 ) (
$length = $_; # loop var would have been aliased
func '', 0;
}
But the length and also the alphabet (@test) should really be
function parameters, not globals.
sub func {
my ($bref, $depth, $length, @alphabet) = (@_);
if ($depth >= $length) {
print "$bref\n";
return;
}
foreach my $var (@alphabet ) {
func("$bref$var", $depth + 1, $length, @alphabet);
}
}
func( '', 0, $_, 'a' .. 'c') for 1 .. 4;
This still isn't very pretty. The first two parameters are only
needed to start the recursion off, the user (of func()) shouldn't
have to deal with them. The standard solution is to make func() an
internal routine "_func_recurs" (say) and give the user (untested):
sub func {
my ( $length, @alphabet) = @_;
_func_recurs( '', 0, $length, @alphabet);
}
There may be better ways to integrate the call.
Anno
------------------------------
Date: Fri, 30 Jul 2004 23:52:26 GMT
From: bowsayge <bowsayge@nomail.afraid.org>
Subject: Re: Brute-Force-like array
Message-Id: <_aBOc.3128$Jp6.1980@newsread3.news.atl.earthlink.net>
Anno Siegel said to us:
[...]
> sub func {
> my ( $length, @alphabet) = @_;
> _func_recurs( '', 0, $length, @alphabet);
> }
>
> There may be better ways to integrate the call.
>
> Anno
ty Anno
--
bowsayge
------------------------------
Date: Fri, 23 Jul 2004 17:28:12 +0100
From: project2501 <project2501@project2501.cor>
Subject: capture/supress stdout from perl module called from cgi
Message-Id: <pan.2004.07.23.16.28.11.594000@project2501.cor>
i have a problem. i'm using apache with perl cgi and the cgi calls
functions from the VCS::CVS module. this is fine... but the
CVS::commit($message) sends items to stdout.
sterr is fine as the webserver redirects that to the apache error logs,
but stdout appears before html stream headers "content type etc" ... and
so the server logs a "malformed header from script. Bad header=..." error
as expected.
i wonder if i can block stdout around that block of code... i've
investigated the use iof eval{} but there don't appear to be options to do
this. the CVS::CVS module itself cannot be set to not output stdout.
any help appreciated.
t
------------------------------
Date: 23 Jul 2004 18:08:06 GMT
From: Eric Bohlman <ebohlman@omsdev.com>
Subject: Re: capture/supress stdout from perl module called from cgi
Message-Id: <Xns952F8665F8607ebohlmanomsdevcom@130.133.1.4>
project2501 <project2501@project2501.cor> wrote in
news:pan.2004.07.23.16.28.11.594000@project2501.cor:
>
> i have a problem. i'm using apache with perl cgi and the cgi calls
> functions from the VCS::CVS module. this is fine... but the
> CVS::commit($message) sends items to stdout.
>
> sterr is fine as the webserver redirects that to the apache error
> logs, but stdout appears before html stream headers "content type etc"
> ... and so the server logs a "malformed header from script. Bad
> header=..." error as expected.
>
> i wonder if i can block stdout around that block of code... i've
> investigated the use iof eval{} but there don't appear to be options
> to do this. the CVS::CVS module itself cannot be set to not output
> stdout.
Would IO::Scalar be any help?
------------------------------
Date: 23 Jul 2004 18:21:19 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: capture/supress stdout from perl module called from cgi
Message-Id: <cdrkuv$i3b$1@mamenchi.zrz.TU-Berlin.DE>
project2501 <project2501@project2501.cor> wrote in comp.lang.perl.misc:
>
> i have a problem. i'm using apache with perl cgi and the cgi calls
> functions from the VCS::CVS module. this is fine... but the
> CVS::commit($message) sends items to stdout.
Well, it shouldn't. No module should print to stdout unless that is
its express purpose.
> sterr is fine as the webserver redirects that to the apache error logs,
I wouldn't call that "fine", but yes, error logs have a big belly.
> but stdout appears before html stream headers "content type etc" ... and
> so the server logs a "malformed header from script. Bad header=..." error
> as expected.
>
> i wonder if i can block stdout around that block of code... i've
> investigated the use iof eval{} but there don't appear to be options to do
> this. the CVS::CVS module itself cannot be set to not output stdout.
Eval is for very different purposes. That it can be used to suppress
unwanted error output bears only a superficial resemblance to your
situation.
The solution depends a bit on what the module actually does. If it
just print()s without a filehandle argument (most likely), select()
is the solution. You need a filehandle to redirect the unwanted
output to (you *could* use STDERR for that, but opening /dev/null may
be a better idea, if available). So (untested):
my $devnull;
open $devnull, ">", $_ or die "Can't write to $_" for '/dev/null';
my $oldfh = select( $devnull);
# code that *prints* *things*
select( $oldfh);
# code that is entitled to print
If the module explicitly prints to STDOUT, stronger medicine is indicated
(and available), but that won't be necessary.
Anno
------------------------------
Date: Fri, 23 Jul 2004 22:34:10 +0300
From: Ilmari Karonen <usenet@vyznev.invalid>
Subject: Re: capture/supress stdout from perl module called from cgi
Message-Id: <slrncg2q1i.vf.usenet@yhteiskone.vyznev.net>
On 2004-07-23, project2501 <project2501@project2501.cor> wrote:
>
> i wonder if i can block stdout around that block of code... i've
> investigated the use iof eval{} but there don't appear to be options to do
> this. the CVS::CVS module itself cannot be set to not output stdout.
You don't mention if the output comes from VCS::CVS itself or from
some external program it calls. In any case, you can capture the
output by reopening STDOUT to a temporary file:
use File::Temp qw(tempfile);
my $tempfile = tempfile() or die "Can't create temp file: $!\n";
open TMPOUT, '>&', \*STDOUT or die "Can't dup stdout: $!\n";
open STDOUT, '>&', $tempfile or die "Can't redirect stdout: $!\n";
# ... do something ...
open STDOUT, '>&', \*TMPOUT or die "Can't restore stdout: $!\n";
seek $tempfile, 0, 0 or die "Can't rewind temp file: $!\n";
my @lines = <$tempfile>;
If you just want to send any output to the bit bucket, that's even
easier:
open TMPOUT, '>&', \*STDOUT or die "Can't dup stdout: $!\n";
open STDOUT, '>/dev/null' or die "Can't redirect stdout: $!\n";
# ... do something ...
open STDOUT, '>&', \*TMPOUT or die "Can't restore stdout: $!\n";
--
Ilmari Karonen
If replying by e-mail, please replace ".invalid" with ".net" in address.
------------------------------
Date: Mon, 26 Jul 2004 12:29:52 +0000 (UTC)
From: Haakon Riiser <hakonrk@fys.uio.no>
Subject: Carp -- shortmess and longmess
Message-Id: <slrncg9ua0.emo.hakonrk@s.hn.org>
perldoc Carp says:
carp - warn of errors (from perspective of caller)
cluck - warn of errors with stack backtrace
(not exported by default)
croak - die of errors (from perspective of caller)
confess - die of errors with stack backtrace
shortmess - return the message that carp and croak produce
longmess - return the message that cluck and confess produce
but this is not how it appears to work. I created a test program
based on the examples in the manual:
--- begin carp.pl ---
use Carp qw(croak cluck);
sub foo {
cluck "This is how we got here!";
print Carp::shortmess("This will have caller's details added");
print Carp::longmess("This will have stack backtrace added");
croak "We're outta here!";
}
sub bar {
foo();
}
bar();
--- end carp.pl ---
When I run this program, I get the following output:
This is how we got here! at carp.pl line 4
main::foo() called at carp.pl line 11
main::bar() called at carp.pl line 14
This will have caller's details added at carp.pl line 5
main::foo() called at carp.pl line 11
main::bar() called at carp.pl line 14
This will have stack backtrace added at carp.pl line 11
main::bar() called at carp.pl line 14
We're outta here! at carp.pl line 7
main::foo() called at carp.pl line 11
main::bar() called at carp.pl line 14
The message from cluck seems to be OK -- it prints the backtrace,
as it should. The next two, shortmess and longmess, appear
to do the opposite of what they should. shortmess prints the
longest message, backtrace and everything, while longmess only
prints the bottom of the stack. It should've been the other
way around, right? croak also prints the full backtrace, which,
if I understand the manual correctly, is incorrect.
In summary: carp, cluck, croak and confess all print the full
backtrace (same as shortmess), and the longmess message is
never used.
Verified on the following systems:
Custom built Perl 5.8.4 (-Duse64bitint -des), Caro 1.02
Custom built Perl 5.8.5 (-Duse64bitint -des), Carp 1.03
Slackware 10's Perl 5.8.4, Carp 1.02
Red Hat Enterprise Linux WS release 3's Perl 5.8.4, Carp 1.02
Is this a known bug, or should I report it with perlbug?
--
Haakon
------------------------------
Date: 26 Jul 2004 22:52:28 GMT
From: Abigail <abigail@abigail.nl>
Subject: Re: Carp -- shortmess and longmess
Message-Id: <slrncgb2pb.6hs.abigail@alexandra.abigail.nl>
Haakon Riiser (hakonrk@fys.uio.no) wrote on MMMCMLXXXII September
MCMXCIII in <URL:news:slrncg9ua0.emo.hakonrk@s.hn.org>:
`' perldoc Carp says:
`'
`' carp - warn of errors (from perspective of caller)
`' cluck - warn of errors with stack backtrace
`' (not exported by default)
`' croak - die of errors (from perspective of caller)
`' confess - die of errors with stack backtrace
`' shortmess - return the message that carp and croak produce
`' longmess - return the message that cluck and confess produce
`'
`' but this is not how it appears to work. I created a test program
`' based on the examples in the manual:
`'
`' --- begin carp.pl ---
`' use Carp qw(croak cluck);
`'
`' sub foo {
`' cluck "This is how we got here!";
`' print Carp::shortmess("This will have caller's details added");
`' print Carp::longmess("This will have stack backtrace added");
`' croak "We're outta here!";
`' }
`'
`' sub bar {
`' foo();
`' }
`'
`' bar();
`' --- end carp.pl ---
`'
`' When I run this program, I get the following output:
`'
`' This is how we got here! at carp.pl line 4
`' main::foo() called at carp.pl line 11
`' main::bar() called at carp.pl line 14
`' This will have caller's details added at carp.pl line 5
`' main::foo() called at carp.pl line 11
`' main::bar() called at carp.pl line 14
`' This will have stack backtrace added at carp.pl line 11
`' main::bar() called at carp.pl line 14
`' We're outta here! at carp.pl line 7
`' main::foo() called at carp.pl line 11
`' main::bar() called at carp.pl line 14
`'
`' The message from cluck seems to be OK -- it prints the backtrace,
`' as it should. The next two, shortmess and longmess, appear
`' to do the opposite of what they should. shortmess prints the
`' longest message, backtrace and everything, while longmess only
`' prints the bottom of the stack. It should've been the other
`' way around, right? croak also prints the full backtrace, which,
`' if I understand the manual correctly, is incorrect.
No, it's not incorrect. You have to read the manual
carefully. longmess/cluck/confess return the stacktrace. Always.
shortmess/carp/croak print the first entry in the stacktrace that isn't
considered "safe". But when everything is "safe", it defaults to printing
the entire stacktrace. The manual also list what is considered safe,
and point 1 says any call into the same package is considered safe.
A small change to your program shows the difference:
#!/usr/bin/perl
use strict;
use warnings;
no warnings qw /syntax/;
use Carp qw(croak cluck);
sub foo {
cluck "This is how we got here!";
print Carp::shortmess("This will have caller's details added");
print Carp::longmess("This will have stack backtrace added");
croak "We're outta here!";
}
package Alien;
sub bar {
main::foo();
}
package main;
Alien::bar();
__END__
This is how we got here! at /tmp/f line 11
main::foo() called at /tmp/f line 19
Alien::bar() called at /tmp/f line 23
This will have caller's details added at /tmp/f line 19
This will have stack backtrace added at /tmp/f line 19
Alien::bar() called at /tmp/f line 23
We're outta here! at /tmp/f line 19
Abigail
--
print v74.117.115.116.32, v97.110.111.116.104.101.114.32,
v80.101.114.108.32, v72.97.99.107.101.114.10;
------------------------------
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.
NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice.
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 6801
***************************************