[24669] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 6833 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Aug 4 11:05:55 2004

Date: Wed, 4 Aug 2004 08: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)

Perl-Users Digest           Wed, 4 Aug 2004     Volume: 10 Number: 6833

Today's topics:
        0 + 1 not an integer? <noone@nowhere.org>
    Re: 0 + 1 not an integer? <usenet@plenz.com>
        @platforms = (sort keys %prj_platforms) || (DEFAULT); (A. Farber)
        Confused by sorting array elements <user@perl.org>
    Re: Confused by sorting array elements <j.g.karssenberg@student.utwente.nl>
    Re: Confused by sorting array elements <egoist99NO@SPAMyahoo.de>
    Re: Confused by sorting array elements (Anno Siegel)
        delimited data into nested array (Yup)
    Re: delimited data into nested array <Joe.Smith@inwap.com>
    Re: delimited data into nested array <noreply@gunnar.cc>
    Re: delimited data into nested array <noreply@gunnar.cc>
    Re: getting line between 2 patterns <someone@example.com>
    Re: getting line between 2 patterns (Anno Siegel)
    Re: join on space instead of comma <bowsayge@nomail.afraid.org>
        recursive functions <me@example.com>
    Re: recursive functions <sholden@flexal.cs.usyd.edu.au>
    Re: recursive functions <me@example.com>
    Re: recursive functions <richard@zync.co.uk>
    Re: RegEx issue (Dan)
    Re: SOAP - undefined handler subroutine (Anno Siegel)
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: Wed, 04 Aug 2004 06:56:15 -0700
From: Philip <noone@nowhere.org>
Subject: 0 + 1 not an integer?
Message-Id: <1091627360.112056@cswreg.cos.agilent.com>

Hi, I am writing a SWIG 1.3 interface to some C++ libraries.

I have a C++ method that goes like:

class MyClass {

    Object Col(int);
    Object Col(const char *);
      :
}

The SWIG overloading mechanism uses SvIOK to test whether to call the first or
the second method.

I find that if I call Col(() from perl like so:

   $intgr = 0;
   $intgr++;
   $myclass->Col($intgr);

It fails because SvIOK fails. Apparent $intgr becomes a number and is no longer
an integer.



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

Date: 4 Aug 2004 14:01:39 GMT
From: Julius Plenz <usenet@plenz.com>
Subject: Re: 0 + 1 not an integer?
Message-Id: <slrnch1r23.uv1.usenet@plenz.com>

* Philip <noone@nowhere.org> [2004-08-04]:
>    $intgr = 0;
>    $intgr++;
>    $myclass->Col($intgr);
> 
> It fails because SvIOK fails. Apparent $intgr becomes a number and
> is no longer an integer.

Just a thought of a newbie - include "use integer;"?

Julius
-- 
www.plenz.com


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

Date: 4 Aug 2004 08:04:33 -0700
From: Alexander.Farber@t-online.de (A. Farber)
Subject: @platforms = (sort keys %prj_platforms) || (DEFAULT);
Message-Id: <c9ccaf83.0408040704.2ac7e6f5@posting.google.com>

Hi,

I must confess, that I don't fully understand the 
difference between an array and a list and suspect 
that the cause for my problem lies somewhere there...

Could someone please explain, why does the code below warns 
"Useless use of sort in scalar context at ./test_case.pl"?

#!/usr/bin/perl -w
use constant DEFAULT => qw(ARMI ARM4 THUMB WINS WINSCW);
@platforms = (sort keys %prj_platforms) || (DEFAULT);

Thank you
Alex


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

Date: 4 Aug 2004 04:39:33 -0500
From: Perl User <user@perl.org>
Subject: Confused by sorting array elements
Message-Id: <4110aed5_1@127.0.0.1>

I have a flat file database that consists of several
variables per line entry.  It's sort of like an address book
file, but has a lot of info in it.  Each line entry contains
the following fields... 

key, firstname, middlename, maidenname, lastname, year, plus
20 more fields. 

I need to be able to display all records for a given year,
sorted by lastname, but when a maidenname is present, which
isn't always the case, it should give precedence to the
maidenname first. 

The unsorted database contents would look like...

100,Bobbie,Allen,,Jones,1982,,,,,,....
102,Julia,Louise,Oldham,Bryant,1982,,,,,....
106,Robert,Mitchell,,Edwards,1955,,,,,....
113,Helen,Irene,,Northcutt,1982,,,,,,....
118,Jennifer,Miranda,Wood,Thomas,1987,,,,,....
121,Robert,James,,Mosby,1982,,,,,,....
129,Mary,Elizabeth,Martin,Davis,1982,,,,,,....

Then the sorted database results for 1982 would look like...

100,Bobbie,Allen,,Jones,1982,,,,,,....
129,Mary,Elizabeth,Martin,Davis,1982,,,,,,....
106,Robert,James,,Mosby,1982,,,,,,....
113,Helen,Irene,,Northcutt,1982,,,,,,....
102,Julia,Louise,Oldham,Bryant,1982,,,,,....

I am thinking that the best way to do this is to go through
the database first and pull out all the records for the year.
 With each pull I would combine maidenname and lastname into
one variable.  Then sort based on the new variable.  

What's the best way to pull each record line into an array of
arrays (consisting of 25 or 26 elements each) and sort on the
fourth variable of each record array for display only,
maintaining the values of all 26 elements? (I don't need to
rewrite the sorted database.  In fact I can't do that.  So 
this sort routine is going to be called for each display 
request the server receives.) 

I really don't understand multidimensional arrays or hashes,
so be gentle with me.

Thanks for any and all assistance.


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

Date: Wed, 4 Aug 2004 11:48:47 +0200
From: Jaap Karssenberg <j.g.karssenberg@student.utwente.nl>
Subject: Re: Confused by sorting array elements
Message-Id: <20040804114847.384fe2dd@captain.student.utwente.nl>

On 4 Aug 2004 04:39:33 -0500 Perl User wrote:
: What's the best way to pull each record line into an array of
: arrays (consisting of 25 or 26 elements each) and sort on the
: fourth variable of each record array for display only,
: maintaining the values of all 26 elements? 

If @records consists of array references you can try something like:

  @records = sort {$$a[4] <=> $$b[4]} @records; # $a and $b are special

See 'perldoc -f sort' for more details.

-- 
   )   (     Jaap Karssenberg || Pardus [Larus]                | |0| |
   :   :     http://pardus-larus.student.utwente.nl/~pardus    | | |0|
 )  \ /  (                                                     |0|0|0|
 ",.*'*.,"   Proud owner of "Perl6 Essentials" 1st edition :)  wannabe


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

Date: Wed, 04 Aug 2004 11:53:59 +0200
From: Robert Meyer <egoist99NO@SPAMyahoo.de>
Subject: Re: Confused by sorting array elements
Message-Id: <pan.2004.08.04.09.53.57.546130@SPAMyahoo.de>

Am Wed, 04 Aug 2004 04:39:33 -0500 schrieb Perl User:

> I have a flat file database that consists of several variables per line
> entry.  It's sort of like an address book file, but has a lot of info in
> it.  Each line entry contains the following fields...
> 
> key, firstname, middlename, maidenname, lastname, year, plus 20 more
> fields.
> 
> I need to be able to display all records for a given year, sorted by
> lastname, but when a maidenname is present, which isn't always the case,
> it should give precedence to the maidenname first.
> 
> The unsorted database contents would look like...
> 
> 100,Bobbie,Allen,,Jones,1982,,,,,,....
> 102,Julia,Louise,Oldham,Bryant,1982,,,,,....
> 106,Robert,Mitchell,,Edwards,1955,,,,,....
> 113,Helen,Irene,,Northcutt,1982,,,,,,....
> 118,Jennifer,Miranda,Wood,Thomas,1987,,,,,....
> 121,Robert,James,,Mosby,1982,,,,,,....
> 129,Mary,Elizabeth,Martin,Davis,1982,,,,,,....
> 
> Then the sorted database results for 1982 would look like...
> 
> 100,Bobbie,Allen,,Jones,1982,,,,,,....
> 129,Mary,Elizabeth,Martin,Davis,1982,,,,,,....
> 106,Robert,James,,Mosby,1982,,,,,,....
> 113,Helen,Irene,,Northcutt,1982,,,,,,....
> 102,Julia,Louise,Oldham,Bryant,1982,,,,,....
> 
> I am thinking that the best way to do this is to go through the database
> first and pull out all the records for the year.
>  With each pull I would combine maidenname and lastname into
> one variable.  Then sort based on the new variable.
> 
> What's the best way to pull each record line into an array of arrays
> (consisting of 25 or 26 elements each) and sort on the fourth variable of
> each record array for display only, maintaining the values of all 26
> elements? (I don't need to rewrite the sorted database.  In fact I can't
> do that.  So this sort routine is going to be called for each display
> request the server receives.)
> 
> I really don't understand multidimensional arrays or hashes, so be gentle
> with me.
> 
> Thanks for any and all assistance.

Try the Schwartzsche-Transformation:

@sorted_lines = map {$_->[0] }
		sort{
			@a_fields = @$a[1..$#$a];
			@b_fields = @$b[1--$#$b];
			$a_fields[3] <=> $b_fields[3] # numeric sort of 4th field
				||
			$a_fields[0] cmp $b_fields[0] # string sort first field then
				||
			$b_fields[2] <=> $a_fields[2] # reverse numeric sort of third field
				||
			....
		}
		map {[$_, split /,/] } @lines; 

HTH
greets
Robert

-- 
There are only 10 types of people in the world:
Those who understand binary, and those who don't.
http://www.one-m.de
http://www.lugbz.org/documents/smart-questions_de.html



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

Date: 4 Aug 2004 10:10:18 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Confused by sorting array elements
Message-Id: <ceqcma$k86$1@mamenchi.zrz.TU-Berlin.DE>

Perl User  <user@perl.org> wrote in comp.lang.perl.misc:
> I have a flat file database that consists of several
> variables per line entry.  It's sort of like an address book
> file, but has a lot of info in it.  Each line entry contains
> the following fields... 
> 
> key, firstname, middlename, maidenname, lastname, year, plus
> 20 more fields. 
> 
> I need to be able to display all records for a given year,
> sorted by lastname, but when a maidenname is present, which
> isn't always the case, it should give precedence to the
> maidenname first. 
>
> The unsorted database contents would look like...
> 
> 100,Bobbie,Allen,,Jones,1982,,,,,,....
> 102,Julia,Louise,Oldham,Bryant,1982,,,,,....
> 106,Robert,Mitchell,,Edwards,1955,,,,,....
> 113,Helen,Irene,,Northcutt,1982,,,,,,....
> 118,Jennifer,Miranda,Wood,Thomas,1987,,,,,....
> 121,Robert,James,,Mosby,1982,,,,,,....
> 129,Mary,Elizabeth,Martin,Davis,1982,,,,,,....
> 
> Then the sorted database results for 1982 would look like...
> 
> 100,Bobbie,Allen,,Jones,1982,,,,,,....
> 129,Mary,Elizabeth,Martin,Davis,1982,,,,,,....
> 106,Robert,James,,Mosby,1982,,,,,,....
> 113,Helen,Irene,,Northcutt,1982,,,,,,....
> 102,Julia,Louise,Oldham,Bryant,1982,,,,,....
> 
> I am thinking that the best way to do this is to go through
> the database first and pull out all the records for the year.

grep

>  With each pull I would combine maidenname and lastname into
> one variable.  Then sort based on the new variable.  

$key = $record[ 3] || $record[ 4];

That isn't quite clean, assuming "0" doesn't occur as a name.

> What's the best way to pull each record line into an array of
> arrays (consisting of 25 or 26 elements each) and sort on the
> fourth variable of each record array for display only,
> maintaining the values of all 26 elements? (I don't need to
> rewrite the sorted database.  In fact I can't do that.  So 
> this sort routine is going to be called for each display 
> request the server receives.) 

What have you tried so far?  Just stating your problem, with an
implied "Please write the program for me" doesn't go over well.

Anno


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

Date: 4 Aug 2004 00:49:07 -0700
From: yaweh32@yahoo.com (Yup)
Subject: delimited data into nested array
Message-Id: <c082ca84.0408032349.7d37e153@posting.google.com>

Hello,
I'm just starting to learn Perl. Up until now I'd been struggling to
learn how to import a tab-delimited data table (from a text file) into
Perl as a two dimensional nested array. I wanted to be able to
manipulate that data by accessing it using x-y coordinates, and then
output it again.

I may have been looking in the wrong place, but I had a hard time
finding help on Google groups and other places online. However, I've
managed to figure it out, and thought I'd post my code.

For two reasons, I suppose - to help other novices, and perhaps get
some comments from more advanced users. On the latter part, I'm
interested in knowing what I could do to make my code run faster and
make it more Perl-ish.

Thanks for your help ahead of time.

#!/usr/local/bin/perl -w

#define filename and open it
$file = 'a1.txt';
open(INFO, $file) || die "Can't open file $file\n" ;

# read file into temporary array called "lines"
while(<INFO>)
{
    #chop off the carrage return
    chop $_;
    push @lines, $_;
}

# Close the file
close(INFO);

#reset index for generating arrays named "line_{$i}" 
$i = 0;

#read each array entry into new array, split with tab
foreach (@lines)
{
    push @{'line_'.${i}}, split("\t", $lines[$i]);
    $i++
}

#generate an array to hold the other arrays
for ($i=0; $i<scalar(@lines); $i++)
{
    push @A, *{'line_'.${i}};
}

#rename the top corner to be START
$A[0][0] = "START";

#open file to send data to
open(OUTFILE, ">a1_edited.txt");

for ($i=0; $i<scalar(@lines);$i++)
{

    for ($j=0;$j<scalar(@line_0);$j++)
    {
	print OUTFILE "$A[$i][$j]";
	if ($j<(scalar(@line_0)-1)) { print OUTFILE "\t";}
    }

    print OUTFILE "\n";
}
close(OUTFILE);


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

Date: Wed, 04 Aug 2004 09:05:00 GMT
From: Joe Smith <Joe.Smith@inwap.com>
Subject: Re: delimited data into nested array
Message-Id: <0F1Qc.208074$IQ4.13553@attbi_s02>

Yup wrote:

> I'm just starting to learn Perl. Up until now I'd been struggling to
> learn how to import a tab-delimited data table (from a text file) into
> Perl as a two dimensional nested array.
> # read file into temporary array called "lines"
> while(<INFO>)
> {
>     #chop off the carrage return
>     chop $_;
>     push @lines, $_;
> }

That can be simplified to just two statements:
	@lines = <INFO>;
	chomp @lines;		# (Don't use chop)

> #read each array entry into new array, split with tab
> foreach (@lines)
> {
>     push @{'line_'.${i}}, split("\t", $lines[$i]);
>     $i++
> }

Ugh!  You're indirectly using symbolic references.  Don't do that.
Use [] to create an anonymous array and push that instead.
	-Joe

   my @lines = <DATA>;
   chomp @lines;
   my @A;                        # Two-dimensional array
   push @A,[split "\t",$_] foreach @lines;
   $A[0][0] = "START";
   $A[2][3] = "Fourth item in third row";
   for my $row (0 .. $#A) {
     print "Row $row: ";
     for my $col (0 .. $#{$A[$row]}) {
       print "\tC$col=$A[$row][$col]";
     }
     print "\n";
   }
__DATA__
zero    one     two     three   four    five    six
ten     eleven  twelve  thirteen
twenty  twenty-one      twenty-two
thirty  thirty-one


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

Date: Wed, 04 Aug 2004 11:29:11 +0200
From: Gunnar Hjalmarsson <noreply@gunnar.cc>
Subject: Re: delimited data into nested array
Message-Id: <2nbomfFujpv4U1@uni-berlin.de>

Yup wrote:
> I'm just starting to learn Perl. Up until now I'd been struggling
> to learn how to import a tab-delimited data table (from a text
> file) into Perl as a two dimensional nested array. I wanted to be
> able to manipulate that data by accessing it using x-y coordinates,
> and then output it again.
> 
> I may have been looking in the wrong place, but I had a hard time 
> finding help on Google groups and other places online. However,
> I've managed to figure it out, and thought I'd post my code.
> 
> For two reasons, I suppose - to help other novices,

Hmm.. To be honest, there is not much for novices to learn from that
code (even if it gets the job done). Actually, it does not even work
the way you say it does: There is no two dimensional array, but rather
a hierarchy of named arrays. There is the array @A that contains
references to a bunch of other named arrays. On top of that, you have
not declared your variables and enabled strictures.

> and perhaps get some comments from more advanced users. On the
> latter part, I'm interested in knowing what I could do to make my
> code run faster and make it more Perl-ish.

Even if I don't consider myself an "advanced" Perl programmer, I made
a suggestion below.

But first a couple of detailed comments:

> #!/usr/local/bin/perl -w

No strictures!

> #define filename and open it

Pointless comment. (It's apparent from the code.)

> $file = 'a1.txt';
> open(INFO, $file) || die "Can't open file $file\n" ;
> 
> # read file into temporary array called "lines"
> while(<INFO>)
> {
>     #chop off the carrage return
>     chop $_;

In Perl 5 you use chomp() for that.

>     push @lines, $_;
> }
> 
> # Close the file

Yes, I can see that. ;-)

> close(INFO);
> 
> #reset index for generating arrays named "line_{$i}"
> $i = 0;
> 
> #read each array entry into new array, split with tab
> foreach (@lines)
> {
>     push @{'line_'.${i}}, split("\t", $lines[$i]);

Here you are using symbolic references, which is normally not
advisable and not allowed under strictures. In this case, there is no
reason to do so.

>     $i++
> }
> 
> #generate an array to hold the other arrays
> for ($i=0; $i<scalar(@lines); $i++)
> {
>     push @A, *{'line_'.${i}};

Symbolic references again.
(Is it possibly Perl 4 style to use globrefs like that?)

> }
> 
> #rename the top corner to be START
> $A[0][0] = "START";
> 
> #open file to send data to
> open(OUTFILE, ">a1_edited.txt");
> 
> for ($i=0; $i<scalar(@lines);$i++)
> {
> 
>     for ($j=0;$j<scalar(@line_0);$j++)
>     {
>       print OUTFILE "$A[$i][$j]";
>       if ($j<(scalar(@line_0)-1)) { print OUTFILE "\t";}
>     }
> 
>     print OUTFILE "\n";
> }
> close(OUTFILE);


How about this instead:

#!/usr/local/bin/perl
use strict;
use warnings;

my @A;
my $file = 'a1.txt';
my $outfile = 'a1_edited.txt';

open IN, $file or die "Can't open $file: $!";
while (<IN>) {
     chomp;
     push @A, [ split /\t/ ];
}
close IN;

$A[0][0] = 'START';

open OUT, "> $outfile" or die "Can't open $outfile: $!";
for (@A) {
     print OUT join "\t", @$_, "\n";
}
close OUT;

__END__


-- 
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl


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

Date: Wed, 04 Aug 2004 12:41:48 +0200
From: Gunnar Hjalmarsson <noreply@gunnar.cc>
Subject: Re: delimited data into nested array
Message-Id: <2nbt07Fv7im5U1@uni-berlin.de>

Joe Smith wrote:
> Yup wrote:
>> 
>> # read file into temporary array called "lines"
>> while(<INFO>)
>> {
>>     #chop off the carrage return
>>     chop $_;
>>     push @lines, $_;
>> }
> 
> That can be simplified to just two statements:
>     @lines = <INFO>;
>     chomp @lines;        # (Don't use chop)

Or to one:

     chomp( my @lines = <INFO> );

But there is no need for any temporary array at all, is there?

     while (<INFO>) {
         chomp;
         push @A, [ split /\t/ ];

-- 
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl


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

Date: Wed, 04 Aug 2004 07:43:49 GMT
From: "John W. Krahn" <someone@example.com>
Subject: Re: getting line between 2 patterns
Message-Id: <Vs0Qc.27146$hw6.8630@edtnps84>

mike wrote:
> 
> i have a file like this:
> 
> 2004nddjjf99jdlkdf   <---- 99 is at character position 11 to 12
> 2004abcdefghijklnmnopqrstuvwxyz
> 2004ldfhanvsduhkjgndfnspqiekfnv
> 2003nmvkdmcnfjfbndmdkvndnmvkdbn
> 2004nddgdf99dkgfjs  
> 
> i wanted to get the text in between the 2 lines that have the number
> "99" at the
> 11th and 12th position. 
> 
> i looked at FAQ ,
> 
> perl -ne 'print if /START/ .. /END/' file1 ...
> 
> how can i define the START and END such that it must check for
> character position 11 and 12 to look for 99 ??

perl -ne 'print if /^.{10}99/ ... /^.{10}99/' file1 ...



John
-- 
use Perl;
program
fulfillment


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

Date: 4 Aug 2004 09:45:13 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: getting line between 2 patterns
Message-Id: <ceqb79$iqg$1@mamenchi.zrz.TU-Berlin.DE>

John W. Krahn <someone@example.com> wrote in comp.lang.perl.misc:
> mike wrote:
> > 
> > i have a file like this:
> > 
> > 2004nddjjf99jdlkdf   <---- 99 is at character position 11 to 12
> > 2004abcdefghijklnmnopqrstuvwxyz
> > 2004ldfhanvsduhkjgndfnspqiekfnv
> > 2003nmvkdmcnfjfbndmdkvndnmvkdbn
> > 2004nddgdf99dkgfjs  
> > 
> > i wanted to get the text in between the 2 lines that have the number
> > "99" at the
> > 11th and 12th position. 
> > 
> > i looked at FAQ ,
> > 
> > perl -ne 'print if /START/ .. /END/' file1 ...
> > 
> > how can i define the START and END such that it must check for
> > character position 11 and 12 to look for 99 ??
> 
> perl -ne 'print if /^.{10}99/ ... /^.{10}99/' file1 ...

That prints the delimitling lines (the ones that contain "99").
Depending on what the OP means by "in between", it might be
necessary to do

    perl -ne 'print if /^.{10}99/ ... /^.{10}99/ and not  /^.{10}99/' file1

Anno


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

Date: Wed, 04 Aug 2004 14:15:26 GMT
From: bowsayge <bowsayge@nomail.afraid.org>
Subject: Re: join on space instead of comma
Message-Id: <2c6Qc.10488$Jp6.7931@newsread3.news.atl.earthlink.net>

LHradowy said to us:

[...]
> What I want to do is elinate the first part of saving it as a comma
> separated file. I belive I can do this in perl, but I can not split on
> spaces since I have spaces that I need to be part of a column. 
[...]

You can extract substrings from your input lines like so:

my (@lines, @fields) = (<>);
chomp @lines;

for (@lines) {
    $fields[0] = substr $_,7,7;
    $fields[1] = substr $_,39,10;
    $fields[2] = substr $_,63;
    local $" = ',';
    print "@fields\n";
}

-- 
my (@str) = split //,'nr iosatrlhewuJ bpneete .';
my (@ndx, @arr) = qw(6 15 4 22 7 2 5 3 11 16 9 10 20 
1 0 12 21 13 18 14 23 8 19 17 24);
$arr[$ndx[$_]] = $str[$_] for (@ndx); print @arr, "\n";



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

Date: Wed, 04 Aug 2004 08:59:12 -0400
From: steve_f <me@example.com>
Subject: recursive functions
Message-Id: <i9n1h09q5obpj2di3o1hg2na6pbdj255ut@4ax.com>

I could never really wrap my mind around the concept
of recursive functions. I'm not sure if this is the right
place to ask...but if anyone can at least clue me in a 
bit, I would really appreciate it.


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

Date: 4 Aug 2004 13:33:47 GMT
From: Sam Holden <sholden@flexal.cs.usyd.edu.au>
Subject: Re: recursive functions
Message-Id: <slrnch1pdr.hht.sholden@flexal.cs.usyd.edu.au>

On Wed, 04 Aug 2004 08:59:12 -0400, steve_f <me@example.com> wrote:
> I could never really wrap my mind around the concept
> of recursive functions. I'm not sure if this is the right
> place to ask...but if anyone can at least clue me in a 
> bit, I would really appreciate it.

A more general programming group might be better...

A recursive function is a function which calls itself. To prevent
inifinite recursion there needs to be at least one case in which
the function doesn't call itself (often called the base case).
Generally the function solves some part of the problem and calls
itself in order to solve the smaller problem that remains. At some
point the smaller problem is so small that the answer is known.

For example here is a non-recursive function to count the number of
strings with the value 'needle' in an array of strings:

sub count_em {
	my $count = 0;
	for my $item (@_) {
		$count++ if $item eq 'needle';
	}
	return $count;
}

It simply looks at each element in the array (@_) and increments the count
if it is 'needle'.

This could also be done recursively.

An obvious base case is the empty array that cleary contains 0 occurances
of the string "needle".

So just the base case would be:

	return 0 if @_ == 0;

For a larger array we can can split it in two, the first element and the
rest of the array. If the first element is "needle" then the answer is
1 + <the number of occurances of "needle" in the rest of the array>, or
just <the number of occurances of "needle" in the rest of the array> if
the first element isn't "needle", in other words:

sub count_em_recursive {
	return 0 if @_ == 0; # the base case

        my $item = shift @_; # solve part of the problem
	my $needle;
	if ($item eq 'needle') {
		$needle = 1;
	} else {
		$needle = 0;
	}

        return $needle + count_em_recursive(@_); # recurse on smaller problem
}

Obviously, this is a remarkably silly thing to do recursively (when
using perl anyway). But examples often suffer from that problem.

Recursion is something a lot of people (in my experience of teaching
anyway) have trouble understanding. It is also one of those things that
seems to "click", and then the person understands...

It's just like "proof by induction" in maths - if you happen to have
done that...

Recursion is usually used with recursive data structures (such as trees) since
a recursive function "maps" easily onto the data structure.

[*]- yes I realise shift operates on @_ by default (in that context), and that
     this is actually a place where the &func; syntax is useful :) - but I
     suspect it would detract from the example...
-- 
Sam Holden


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

Date: Wed, 04 Aug 2004 10:20:53 -0400
From: steve_f <me@example.com>
Subject: Re: recursive functions
Message-Id: <a5s1h0l40u94qrr6ulco6l3cpkvj18cpeo@4ax.com>

OK thanks, now I have two working examples. I took a year of calculus,
but don't think I ever encountered "proof by induction".

This concept has never really clicked for me. For example, I wouldn't
recognize what type of problem would need a recursive solution.

I know the concept is a function calls itself repeatedly until it
runs out and now that there is a base case.

example one:
#!/usr/bin/perl -w
@array = qw( test_1 test_2 test_3 );
print count_em_recursive(@array);
sub count_em_recursive {
    return 0 if @_ == 0; # the base case
        my $item = shift @_; # solve part of the problem
    my $needle;
    if ($item eq 'needle') {
        $needle = 1;
    } else {
        $needle = 0;
    }
        return $needle + count_em_recursive(@_); # recurse on smaller problem
}

example two:
#!/usr/bin/perl -w
$string = "test_1\ntest_2\ntest_3";
print combine($string);
sub combine {
   my @words = split /\n/, shift;
   return @words unless @_;
   my @combinations;
   for my $word (@words) {
      push @combinations => map { "$word $_" } combine(@_);
   }
   @combinations;
}


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

Date: Wed, 04 Aug 2004 15:57:35 +0100
From: "Richard Gration" <richard@zync.co.uk>
Subject: Re: recursive functions
Message-Id: <ceqth0$1r9$1@news.freedom2surf.net>

In article <i9n1h09q5obpj2di3o1hg2na6pbdj255ut@4ax.com>, "steve_f"
<me@example.com> wrote:

> I could never really wrap my mind around the concept of recursive
> functions. I'm not sure if this is the right place to ask...but if
> anyone can at least clue me in a bit, I would really appreciate it.

The absolute classic example of a recursive algorithm is the factorial
function. This relies on the relationship

n! = n * (n-1)!

and the fact that

1! = 1

so the code pretty much writes itself ...

#!/usr/bin/perl

my $f = shift;
print "$f! = ",factorial($f),"\n";

sub factorial {
    my $n = shift;

    if ($n == 1) {
	# base case
        return 1;
    } else {
        return $n * factorial($n-1);
    }
}

HTH
Rich


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

Date: 4 Aug 2004 06:38:47 -0700
From: dodonnell@gmail.com (Dan)
Subject: Re: RegEx issue
Message-Id: <6e52dd80.0408040538.fe5229e@posting.google.com>

Thanks for the help - I still wasn't able to get that code working
however.
I am interested in using one of the HTML parsers on CPAN, but they all
seem somewhat confusing to me. I can't seem to figure out how they
operate and how I might use them to extract and manipulate links from
some HTML stored in a string. If anyone knows any tutorials or
dumbed-down examples around the web, I'd very much appreciate a link!

Dan


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

Date: 4 Aug 2004 08:44:52 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: SOAP - undefined handler subroutine
Message-Id: <ceq7m4$fhf$2@mamenchi.zrz.TU-Berlin.DE>

Aaron Couts  <spam@couts.org> wrote in comp.lang.perl.misc:
> I had SOAP working last night and now it's mysteriously not working.  I'm 
> trying to get a test script going with SOAP::Lite, Apache, and mod_perl.
> Whenever I call my routine, I Apache gives me:
> -------------
> [Tue Aug  3 19:29:24 2004] [error] Undefined subroutine 
> &SOAP::ServerDemo::handler called.

The sub "handler" is missing from package SOAP::ServerDemo.

> -------------
> Here's my ServerDemo.pm (straight from the SOAP::Transport::HTTP::Apache doc):
> -------------
> package ServerDemo;
>     use SOAP::Transport::HTTP::Apache;
>     sub handler {

This defines a sub "handler" in package ServerDemo.  You need one
in SOAP::ServerDemo.

Anno



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

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 6833
***************************************


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