in reply to Re: Passing Empty/ Undefined values to a subroutine
in thread Passing Empty/ Undefined values to a subroutine

I would pass a reference to a hash array.
  • Comment on Re: Re: Passing Empty/ Undefined values to a subroutine

Replies are listed 'Best First'.
Re: Re: Re: Passing Empty/ Undefined values to a subroutine
by tilly (Archbishop) on Jun 22, 2003 at 23:30 UTC
    I prefer giving answers which I believe the asker will understand.

    While there is something to be said for passing an anonymous hash if you have a lot of arguments, understanding that requires references, which someone who is still figuring out the calling semantics probably isn't ready to deal with. Also I hate leaving someone confused in a position where they feel, "I don't know why that didn't work, I don't know why this does, it is all magic to me." That leads to fear and cargo-cult programming.

    However since you apparently do understand that answer, I'll give you another one. Read Pass by reference vs globals to see some of the issues that using references to hash arrays for lots of parameters can allow to grow...

      Hi, I have attached the code and output below.. Thanks #! /usr/bin/perl print "Testing Subroutine parameter passing\n"; my $var1 = "var1"; my $var2 = "var2"; my_sub1($var1, $var2); print "End Test\n"; sub my_sub1 { my $var1 = shift; my $var2 = shift; my ($var3, $var4); my @undef1 = (); if ($var1 eq "var2") { $var3 = $var1; } if ($var2 eq "var2") { $var4 = $var2; } print_vars($var1, $var3, @undef1, $var4); } sub print_vars{ my $var1 = shift; my $var3 = shift; my @undef1 = shift; my $var4 = shift; print "Var1: $var1\n"; print "var3: $var3\n"; print "undef1: @undef1\n"; print "var4: $var4\n"; } OUTPUT: Testing Subroutine parameter passing Var1: var1 Use of uninitialized value in concatenation (.) at ./passtest.pl line +32. var3: undef1: var2 Use of uninitialized value in concatenation (.) at ./passtest.pl line +34. var4: End Test
        First a painful nit. Any experienced programmer relies on indentation to read code. Most will simply refuse to read any lengthy piece of unformatted code. itiskindoflikereadingsentenceswithnocapitalsorwhitespace,youcandoitbutitisnotfun.

        To get a sense what your code looks like when formatted, download perltidy and run it. For discussion of why indentation matters (and virtually everything else about basic coding technique) the reference that I highly recommend is Code Complete. Don't be fooled by its age or the fact that Perl is not among the languages used as examples, its advice is timeless and very relevant.

        Back to Perl. Here is your confusion. @undef1 is an array which can have 0, 1 or many elements. You initialize it to none. Perl passes arguments into a function as a single list. In particular that array will be flattened out and take up 0, 1, or many arguments. In your case the array has nothing in it and so contributes no elements to the list. However in print_vars you are assuming that it has one element. Essentially your function call boils down to:

        print_vars("var1", undef, (), "var2");
        and the arguments are interpolated into the list:
        "var1", undef, "var2"
        and then you place "var1" into $var1, undef into $var3, "var2" into the array @undef1, and nothing is left to go into $var2.

        This behaviour is described in perldata, look for the words, LISTs do automatic interpolation of sublists. Yeah, I know. It says it, but making heads or tails of it takes concentration and work. That is why people buy books like Learning Perl that say important parts of the documentation, but in an easier to read form. (Of course at some point it is important to become used to reading documentation, but take it one step at a time.)