Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations MikeeOK on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

The myth of calling subroutine 2

Status
Not open for further replies.

whn

Programmer
Oct 14, 2007
265
US
Please see the sample code below:

Code:
#! /usr/bin/perl

use strict;
use warnings;

my $var = "a";
&func1($var, 'b');
&func2;
exit;

sub func1 {
  my ($v1, $v2) = @_;
  &func3;
  &func4[b][COLOR=red]()[/color][/b]; # the parenthesis makes a difference!!
}

sub func2 {
  my $v1 = "a";
  my $v2 = 'b';
  &func5;
  &func6();
}

sub func3 {
  my ($v1, $v2) = @_;
  print "In func3. \$v1 = $v1, \$v2 = $v2\n";
}

sub func4 {
  my ($v1, $v2) = @_;
  print "In func4. \$v1 = $v1, \$v2 = $v2\n"; # line 31
}

sub func5 {
  my ($v1, $v2) = @_;
  print "In func5. \$v1 = $v1, \$v2 = $v2\n"; # line 36
}

sub func6 {
  my ($v1, $v2) = @_;
  print "In func6. \$v1 = $v1, \$v2 = $v2\n"; # line 41
}

While func1 calls func3 & func4, the private variables $v1 & $v2 in func1 are implicitly passed into func3, but not into func4. Apparently, the parenthesis in red makes a significant difference.

While func2 calls func5 & func6, the private variable $v1 & $v2 in func2 can not be implicitly passed into either func5 or func6.

Could someone please explain to me why there are such differences? I cannot see any advantages of this implicitly passing. Nor do I understand why $v1 & $v2 in func2 can not be implicitly passed into func5.

Below is the output of a test run:
Code:
% tt.pl
In func3. $v1 = a, $v2 = b
Use of uninitialized value in concatenation (.) or string at ./callSub2.pl line 31.
Use of uninitialized value in concatenation (.) or string at ./callSub2.pl line 31.
In func4. $v1 = , $v2 =
Use of uninitialized value in concatenation (.) or string at ./callSub2.pl line 36.
Use of uninitialized value in concatenation (.) or string at ./callSub2.pl line 36.
In func5. $v1 = , $v2 =
Use of uninitialized value in concatenation (.) or string at ./callSub2.pl line 41.
Use of uninitialized value in concatenation (.) or string at ./callSub2.pl line 41.
In func6. $v1 = , $v2 =
 
Quoted from perlsub
Subroutines may be called recursively. If a subroutine is called using the & form, the argument list is optional, and if omitted, no @_ array is set up for the subroutine: the @_ array at the time of the call is visible to subroutine instead. This is an efficiency mechanism that new users may wish to avoid.

Code:
    &foo(1,2,3);	# pass three arguments
    foo(1,2,3);		# the same
    foo();		# pass a null list
    &foo();		# the same
    &foo;		# foo() get current args, like foo(@_) !!
    foo;		# like foo() IFF sub foo predeclared, else "foo"

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
At a guess, I reckon it has nothing to do with $v1 & $v2 being implicitly passed anywhere (how could they be when you declare new [tt]my[/tt] variables in each function?), and more to do with @_.

You pass an "a" and a "b" into func1 which copies them out of @_ into local $v1 & $v2 variables. It then calls &func3 without brackets which, I'm guessing, causes the same @_ to be picked up by &func3 into its version of $v1 and $v2. When you call &func4 with empty brackets, that sends an empty @_ for it to play with.

&func2 has no parameters in @_ in the first place.



-- Chris Hunt
Webmaster & Tragedian
Extra Connections Ltd
 
Thank you both, Kevin and Chris.

This helps me a lot! But it'll take some time for me to understand why it is more efficient, though.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top