-1

I have a variable currentUser in a sub routine. It carries through to one subroutine, but does not carry through to another subroutine. How can I pass a variable through multiple subroutines while keeping the value?

sub login {
    &app_header;
    print <<EOF;
<form name="macform" method="POST" enctype="application/x-www-form-urlencoded"       action="$fullurl">
    ...stuff
    EOF  
}

sub html_menu {
    $me = $currentUser;
    print $me;
    print <<EOF;
    <form name="menuform" method="POST" enctype="application/x-www-form-urlencoded"     action="$fullurl">
    ..stuff
    EOF
    &app_list_button;
    print "<br>";
    &app_search_button;
    print "<br>";
    &app_edit_button;
    print "</div>";
}

When I attempt to do the same thing the html_form sub does with currentUser in a new sub called after html_form), the variable does not display as what the user entered during login.

TLP
  • 66,756
  • 10
  • 92
  • 149
RichDiet
  • 13
  • 3
  • 1
    This would be a better question if you would include a short code snippet showing what you are trying to do and what you expect to happen. – mob Nov 12 '12 at 17:08
  • Show the html_form sub as well... you don't have to include anything not related to the variable. – TLP Nov 12 '12 at 17:20
  • 4
    I stand corrected. The code snippet and explanation are not making this a better question. – mob Nov 12 '12 at 18:17

3 Answers3

3
sub first {
    my $currentUser = shift;
    second($currentUser);
}

sub second {
    my $currentUser = shift;
    third($currentUser);
}

...and so on.

Passing a variable as argument is done through the @_ variable. You should not attempt to use global variables, it is not a good way to do it. You can do it like so:

my ($arg1, $arg2, @rest) = @_;

Or by using shift, pop and the other methods of manipulating arrays, like I above used shift.

If you are not already doing so, I recommend very strongly that you use

use strict;
use warnings;

It will help you solve many simple problems.

TLP
  • 66,756
  • 10
  • 92
  • 149
  • This worked perfectly for me. Thanks for the help! Pardon my perl stupidity. – RichDiet Nov 12 '12 at 18:27
  • @user1703986 You're welcome. You should only call subs with the `name($arg)` method, unless you explicitly are trying to achieve something different, which is described in perldoc perlsub. – TLP Nov 12 '12 at 18:44
2

The safest way is to use the variable as an argument:

sub r1 {
    my $arg = shift;
    r2($arg);
}

sub r2 {
    my $arg = shift;
    print "$arg in r2\n";
}
choroba
  • 231,213
  • 25
  • 204
  • 289
1

When I attempt to do the same thing the html_form sub does with currentUser in a new sub called after html_form), the variable does not display as what the user entered during login.

Firstly, this is a rather complex example. You should have tried to break it down. To add to what others have said thus far, I'm going to tell you the & prefix on a subroutine's name without adding () changes the meaning. You use this in your examples, and I'm not sure if you know what it does. All of these have slightly different meanings.

  • foo() This simply calls sub foo with no arguments.
  • &foo This calls foo passing in @_ implicitly. Important note, if foo modifies @_ by reference then the @_ will change for the callee too.
  • &foo() This is just a relic of perl4. This calls foo with the explicit subref sigil. This is deprecated in all contexts.

there are also minor differences with prototypes and the & sigil that are outside of the bounds of the question

For more information see perldoc -q "calling a function" and perldoc perlsub

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468