aatrox has asked for the wisdom of the Perl Monks concerning the following question:

Subroutine parameters problem

Hello i was trying to make subroutine to print names of people to have less of writting but this doesnt work and i dont know which parameters i should use i was trying everything which come to my brain. If somebody can look at it and tell me what parameters should be inside function i would be thankful. Here is code
elsif($winners eq "denmark\n") { print "Denmark - people at competition:\n"; foreach $guest(@people) { if(length($guest->{'id'}) == 15 && $guest->{'id'} =~ /^20[ +0-5]|^26|^28/) { &write(#dont know what parameters should give) } } } # My function sub write { print "$guest->{'surname'} "; print "$guest->{'name'}"; print ":$guest->{'id'}\n"; } If i do it like this it works without problem elsif($winners eq "denmark\n") { print "Denmark - people at competition:\n"; foreach $guest(@people) { if(length($guest->{'id'}) == 15 && $guest->{'id'} =~ /^20[ +0-5]|^26|^28/) { print "$guest->{'surname'} "; print "$guest->{'name'}"; print ":$guest->{'id'}\n"; } } }

Replies are listed 'Best First'.
Re: Problem with parameters in subroutines
by choroba (Cardinal) on Jun 02, 2014 at 12:15 UTC
    As written, you subroutine can be called without parameters. Note that write is not a good subroutine name, though, as write already has a meaning in Perl.

    On the other hand, you can write the subroutine in a way it expects a parameter:

    sub mywrite { my $candidate = shift; print "$candidate->{firstname} $candidate->{surname}:$candidate->{ +id}\n"; }

    This still look wrong, though. What's the relation between $guest and $kandydatkonkursu?

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      its the same it was my big fault i forgot to translate subroutine sorry :F
      Yeah this works !! Thank you so much!
Re: Problem with parameters in subroutines
by smls (Friar) on Jun 02, 2014 at 12:32 UTC

    Others have already answered your more immediate question, but from the way you asked, it looks like you may have a misconception about how subroutine parameters work in the first place.

    All that passing parameters to a subroutine call does, is to make those values available to the subroutine in the special @_ array.
    It does not automatically make each parameter a variable inside the subroutine, and in fact it won't have any effect at all if the subroutine does not choose to look at the contents of @_.

    Often, "looking at the contents of @_" is done implicitly using calls to shift, hence the  my $candidate = shift; in the above answer.

    If you need more explanation, please read perlintro#Writing-subroutines.

      Ok thanks for explanation. Im already learning perl from yesterday and sometimes it looks strange for me :) I have got next question with loops: If i have got loop:
      foreach $guest(@people) { if($guest->{'ident'} =~ /^1[014689]*7[014689]*5[014689]*3[ +014689]*2[014689]*$/) { mywrite($guest); #my print function } }
      And i want change this foreach loop to for loop it should looks like that?
      $arraylenght = lenght($guests); for($i = 0 ; i < $arraylenght ; $i++) { }
      Im thinking how i can change this loop foreach to for loop workinkg for this example im trying to do this to practise. I was reading abour foreach loop and i think here guests is a array of people and &guest are one person from this array. Is it maybe possible to do something like this?
      $arraylenght = lenght($guests); for($i = 0 ; i < $arraylenght ; $i++) { if($guest->{'ident'} =~ /^1[014689]*7[014689]*5[014689]*3[014689]*2[01 +4689]*$/) { mywrite($guest); #my print function } }

        This is how you would write it as a C-style for loop:

        for (my $i=0; $i <= $#people; $i++) { if($people[$i]{'ident'} =~ /^1[014689]*7[014689]*5[014689]*3[01468 +9]*2[014689]*$/) { mywrite($people[$i]); #my print function } }

        Comments:

        • @people is an array, and $people[$i] is the element with index $i in that array. The foreach version of the loop automatically maps the current array element to a new variable ($guest in this case) which is nicer to type and read than $people[$i], which is why that kind of loop is usually preferable.

        • $#people is the correct syntax for referring to the last index of the @people array. The length function is only used to get the length of a string, not the number of elements in an array.

        In any case, I strongly recommend that you carefully read through the whole perlintro page (and especially the "Perl variable types" section); it will make learning Perl much easier than trying to figure out the basics by trial-and-error. After that, perlreftut makes for good further reading.

        ---
        Update: Fixed link; thanks taint!

Re: Problem with parameters in subroutines
by LanX (Saint) on Jun 02, 2014 at 12:11 UTC
    sub write { my ($contestant) = @_; print "$contestant->{'nazwisko'} "; print "$contestant->{'imie'}"; print ":$contestant->{'id'}\n"; }

    it's hard to tell from the code given¹ how to best call write()

    If your claims are right, this should work  write($kandydatkonkursu) ...

    ...but I think it should rather be  write($guest)!

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    ¹) including Polish(?) variable names mixed with English ... ;-)

    update
    • s/kandydat/contestant/ # "unpolished" variable name ;)
    • as choroba++ already noted: write is a bad choice, maybe better put_out() or just 'out()'?
      Thanks for the answer. I have done as you said and i got Not a GLOB reference at dziala.pl error, sorry for my code i will repair it i wanted to translate it from polish to english but forgot to change working part withour subroutine :)
        > ... from polish to english but forgot ...

        Look for me it doesn't matter how you name your variables as long as your code...

        • has a consistent language
        • and is working.
        (just don't expect it to be self-documenting for too many people ;)

        Regarding you error please post working code which reproduces the problem.

        Cheers Rolf

        ( addicted to the Perl Programming Language)