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

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

Replies are listed 'Best First'.
Re: Re: Re: Re: Re: Passing Empty/ Undefined values to a subroutine
by tilly (Archbishop) on Jun 23, 2003 at 05:49 UTC
    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.)