f



perl sub and perl modules

Hi all,


I am new in perl and I am having some difficulties in getting used to it.
I have an array of array:

my @hap = (
     [qw/ a c g t g c/],
     [qw/ c g ? t a g/],
     [qw/ a c t t ? c/]);


and as during the process I will need to print how this evolves during the
process, I tried to place a print sub:


sub MyPrint {
    my (@arr) =@_;

    for my $i (0..$#arr){
        for my $j (0..$#{$arr[$i]}){
            print $arr[$i][$j]."\t";
        }
        print "\n";
    }
}


if I call my print as reference:

MyPrint(\@hap);

I get:
ARRAY(0x541c)   ARRAY(0x7b944)  ARRAY(0x7b884)

instead if I pass the array as value:

MyPrint(@hap);

I get the answer I was trying to get.

a       c       g       t       g       c
c       g       ?       t       a       g
a       c       t       t       ?       c


But As I think that passing as value (creates a variable that we are not
going to use anymore ) I think the best idea was passing by reference,
but..

How I do that?


Alternatively I was thinking to place My sub in a module. How this will
work on that situation?


Thanks in advance for you help

P
0
pedro
9/18/2003 11:45:56 AM
comp.lang.perl.misc 33233 articles. 2 followers. brian (1246) is leader. Post Follow

4 Replies
1053 Views

Similar Articles

[PageSpeed] 43

fabre <pedro.fabre@gen.gu.se> wrote in comp.lang.perl.misc:
> Hi all,
> 
> 
> I am new in perl and I am having some difficulties in getting used to it.
> I have an array of array:
> 
> my @hap = (
>      [qw/ a c g t g c/],
>      [qw/ c g ? t a g/],
>      [qw/ a c t t ? c/]);
> 
> 
> and as during the process I will need to print how this evolves during the
> process, I tried to place a print sub:
> 
> 
> sub MyPrint {
>     my (@arr) =@_;
> 
>     for my $i (0..$#arr){
>         for my $j (0..$#{$arr[$i]}){
>             print $arr[$i][$j]."\t";
>         }
>         print "\n";
>     }
> }

That's more complicated than it has to be.  Don't use array indices in
Perl unless you have to.  Here is a simplified version:

    sub MyPrint {
        for ( @_ ) {
            print join( "\t", @$_), "\n";
        }
    }


> 
> 
> if I call my print as reference:
> 
> MyPrint(\@hap);
> I get:
>
> ARRAY(0x541c)   ARRAY(0x7b944)  ARRAY(0x7b884)
> 
> instead if I pass the array as value:
> 
> MyPrint(@hap);
> 
> I get the answer I was trying to get.
> 
> a       c       g       t       g       c
> c       g       ?       t       a       g
> a       c       t       t       ?       c
> 

Sure.  That calls MyPrint with a single scalar parameter, which is
a listref.  The way you layed out the routine, it expects a list
(of listrefs).

> But As I think that passing as value (creates a variable that we are not
> going to use anymore ) I think the best idea was passing by reference,
> but..
> 
> How I do that?

To make it work with a reference, change the loop control in "for"

    sub MyPrint {
        for ( @{ shift()} ) {
            print join( "\t", @$_), "\n";
        }
    }

> Alternatively I was thinking to place My sub in a module. How this will
> work on that situation?

You would define the routine in a module exactly the way you do it
in your main file.

Anno
0
anno4000
9/18/2003 12:14:29 PM
But in the case I want to change the values to upper case or modify them,
then I will need to use indexes in perl. right?


sub toUpperCase {
    my (@arr) =@_;

    for my $i (0..$#arr){ 
        for my $j (0..$#{$arr[$i]}){ 
            $arr[$i][$j] =~ tr/[a-z]/[A-Z]/;   # convert to upper case 
        }
    }
}

that doesn't work either.

how this will work passing as references?

Thanks

P

PS: I cam from java and migrate to perl seems to be not an easy task!

In article <bkc7j5$2un$1@mamenchi.zrz.TU-Berlin.DE>,
anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) wrote:

> fabre <pedro.fabre@gen.gu.se> wrote in comp.lang.perl.misc:
> > Hi all,
> > 
> > 
> > I am new in perl and I am having some difficulties in getting used to it.
> > I have an array of array:
> > 
> > my @hap = (
> >      [qw/ a c g t g c/],
> >      [qw/ c g ? t a g/],
> >      [qw/ a c t t ? c/]);
> > 
> > 
> > and as during the process I will need to print how this evolves during the
> > process, I tried to place a print sub:
> > 
> > 
> > sub MyPrint {
> >     my (@arr) =@_;
> > 
> >     for my $i (0..$#arr){
> >         for my $j (0..$#{$arr[$i]}){
> >             print $arr[$i][$j]."\t";
> >         }
> >         print "\n";
> >     }
> > }
> 
> That's more complicated than it has to be.  Don't use array indices in
> Perl unless you have to.  Here is a simplified version:
> 
>     sub MyPrint {
>         for ( @_ ) {
>             print join( "\t", @$_), "\n";
>         }
>     }
> 
> 
> > 
> > 
> > if I call my print as reference:
> > 
> > MyPrint(\@hap);
> > I get:
> >
> > ARRAY(0x541c)   ARRAY(0x7b944)  ARRAY(0x7b884)
> > 
> > instead if I pass the array as value:
> > 
> > MyPrint(@hap);
> > 
> > I get the answer I was trying to get.
> > 
> > a       c       g       t       g       c
> > c       g       ?       t       a       g
> > a       c       t       t       ?       c
> > 
> 
> Sure.  That calls MyPrint with a single scalar parameter, which is
> a listref.  The way you layed out the routine, it expects a list
> (of listrefs).
> 
> > But As I think that passing as value (creates a variable that we are not
> > going to use anymore ) I think the best idea was passing by reference,
> > but..
> > 
> > How I do that?
> 
> To make it work with a reference, change the loop control in "for"
> 
>     sub MyPrint {
>         for ( @{ shift()} ) {
>             print join( "\t", @$_), "\n";
>         }
>     }
> 
> > Alternatively I was thinking to place My sub in a module. How this will
> > work on that situation?
> 
> You would define the routine in a module exactly the way you do it
> in your main file.
> 
> Anno
0
pedro
9/18/2003 1:10:17 PM
fabre <pedro.fabre@gen.gu.se> wrote:

[ don't top post ]

> But in the case I want to change the values to upper case or modify 
> them, then I will need to use indexes in perl. right?

No!
 
It's much easier (and more efficient) to loop over the arrays directly,
rather than looping over temporary lists of indices.

  sub to_upper {
    for my $ref (@_) {
      $_ = uc for @$ref;
    }
  }

> PS: I cam from java and migrate to perl seems to be not an easy task!

You just have to lose your taste for doing things the "hard way".

-- 
Steve
0
Steve
9/18/2003 2:16:12 PM
[ Please do not top-post.  Please do not full-quote. ]


fabre <pedro.fabre@gen.gu.se> wrote:
> But in the case I want to change the values to upper case or modify them,
> then I will need to use indexes in perl. right?


Wrong.


> sub toUpperCase {
>     my (@arr) =@_;
> 
>     for my $i (0..$#arr){ 
>         for my $j (0..$#{$arr[$i]}){ 
>             $arr[$i][$j] =~ tr/[a-z]/[A-Z]/;   # convert to upper case 


tr/// does not respect locales, so it does NOT convert to upper case,
it converts characters.

Why are you asking tr/// to replace "[" with "[" and "]" with "]" ?


>         }
>     }
> }
> 
> that doesn't work either.


It worked when I tried it, so I can't help you with that part.


> PS: I cam from java and migrate to perl seems to be not an easy task!


Perl has many operators that operate on lists (such as foreach), so
you very seldom _need_ to do explicit indexing yourself. 

You are human, you may make a mistake. 

perl is a machine, it will do the right thing everytime.

You should catch yourself whenever you find yourself doing explict
indexing, you are likely thinking in some other language and there
is a more Perlish way of accomplishing the same thing.

You can rewrite your uppercasing to have perl do the indexing
for you too:

-----------------------------------------
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my @hap = (
      [qw/ a c g t g c/],
      [qw/ c g ? t a g/],
      [qw/ a c t t ? c/]);

toUpperCase(@hap);
print Dumper \@hap;


sub toUpperCase {
    my (@arr) =@_;

    foreach my $aref ( @arr ){
        foreach my $value ( @$aref ){
            $value = uc $value;
        }
    }
}
-----------------------------------------




[ snip 90 lines of TOFU ]

-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas
0
tadmc
9/18/2003 2:56:42 PM
Reply: