Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Another scoping issue: How do I send 2 variables to my sub and use both.

by MikeDexter (Sexton)
on Feb 05, 2010 at 16:17 UTC ( [id://821596]=perlquestion: print w/replies, xml ) Need Help??

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

I have a sub that can fetch the network information of a host. The sub looks like this:

for my $nic (networkInfo()) { if (defined $nic->{ip}) { print ">>> IP4 Device: $nic->{device} is using: $nic->{ip +} address\n" . "\tMask: $nic->{mask}\n" . "\tBroadcast: $nic->{bcast}\n"; } if (defined $nic->{ip6}) { print ">>> IP6 Device: $nic->{device} is using: $nic->{ip6} a +ddress\n"; } }

The print lines are working, note how the print uses a $nic->{} variable. Okay, so now I want to send 2 variables into a new sub. These two variables are

$platform and $nic->{device}

I have a new sub call that tries to do this but when I get into the subroutine code itself, I don't know how to access the 2nd variable $nic->{device}

Here is the code for my call and the sub so you can see what I am trying to do....

CALL

my @files = getPlatformFiles($platform, $nic->{device}); foreach my $file (@files) { print "$file\n"; }

SUB

sub getPlatformFiles { my $plat_in = shift; my @list; if ($plat_in =~ /RedHat/) { @list = ("/etc-test/resolv.conf", "/etc-test/sysconfig/network-scripts/ifcfg-$nic->{de +vice}"); } return @list; }

When I run the code I get an message telling me the following: (ignore the line numbers please)

Global symbol "$nic" requires explicit package name at ./new.pl line 1 +85. Execution of ./new.pl aborted due to compilation errors (#1) (F) You've said "use strict vars", which indicates that all variab +les must either be lexically scoped (using "my"), declared beforehand +using "our", or explicitly qualified to say which package the global var +iable is in (using "::"). Uncaught exception from user code: Global symbol "$nic" requires explicit package name at ./new.p +l line 185. Execution of ./new.pl aborted due to compilation errors. at ./new.pl line 189

Line 185 is the line in the sub itself with the  $nic->{device} variable

Replies are listed 'Best First'.
Re: Another scoping issue: How do I send 2 variables to my sub and use both.
by kennethk (Abbot) on Feb 05, 2010 at 16:34 UTC
    As detailed in DESCRIPTION in perlsub, variables passed into a subroutine are stored in the special @_ array. The shift at the start of your subroutine implicitly accesses this array. Since $nic is presumably a hash reference and thus a scalar, you could access it with:

    sub getPlatformFiles { my $plat_in = shift; my $nic = shift; my @list;

    A style I prefer when not using OO-style programming is to use an list assignment rather than a shift, but this is wholly subjective:

    sub getPlatformFiles { my ($plat_in, $nic) = @_; my @list;

    There are some potential complexities involved in scoping here, which may bite you if you are incautious and use the same variable names in a script and a subroutine. Note the following is for demonstration purposes and using this approach without good reason can result in some painful bug hunting. If you declare a variable with my in scoping using that contains a subroutine, that subroutine can see all variables in that scope, and hence the following works:

    #!/usr/bin/perl use strict; use warnings; my $variable = "Hello\n"; outputter(); sub outputter { print $variable; }

    This is because the scope of $variable is at the script level and contains the subroutine definition. On the other hand, the following will output an error message:

    #!/usr/bin/perl use strict; use warnings; sub outputter { print $variable; } my $variable = "Hello\n"; outputter();
    because the variable is not declared prior to its use in the subroutine. These behaviors allow for some very powerful structures called closures.

      I have tried it both ways and I am getting a message about "use of uninitialized value in concat......"

      sub getPlatformFiles { # my ($plat_in, $nic_in) = @_; my $plat_in = shift; my $nic_in = shift; my @list; print "<$plat_in>\n"; #debugging print "<$nic_in>\n"; #debugging if ($plat_in =~ /RedHat/) { @list = ("/etc-test/resolv.conf", "/etc-test/sysconfig/network-scripts/ifcfg-$nic->{de +vice}"); } return @list; }

      The first debugging has the correct value but the second is blank empty. It prints <>

        "/etc-test/sysconfig/network-scripts/ifcfg-$nic->{device}");

        should read

        "/etc-test/sysconfig/network-scripts/ifcfg-$nic_in->{device}");

        - you missed a search and replace. If you are using strict and it did not get caught, that would be for the reason I detailed before.

        If print "<$nic_in>\n"; is not outputting something that looks like <HASH(0x236e88)>, then you are passing it an undefined value. Are you calling the subroutine with something that looks like getPlatformFiles($platform,$nic);? Are you sure $nic is defined?

Re: Another scoping issue: How do I send 2 variables to my sub and use both.
by starX (Chaplain) on Feb 05, 2010 at 16:29 UTC
    Highly untested, but try this:
    sub getPlatformFiles { my $plat_in = shift; my $nic = shift; my @list; if ($plat_in =~ /RedHat/) { @list = ("/etc-test/resolv.conf", "/etc-test/sysconfig/network-scripts/ifcfg-$nic->{de +vice}"); } return @list; }
    You're passing in a list of two elements, so you need to shift the second one onto a more localized variable in order to access it within the subroutine.
Re: Another scoping issue: How do I send 2 variables to my sub and use both.
by hexcoder (Curate) on Feb 06, 2010 at 13:05 UTC
    If you call it like this:

    my @files = getPlatformFiles($platform, $nic->{device});
    your sub should look like this

    sub getPlatformFiles { my $plat_in = shift; my $nic_device_in = shift; my @list; if ($plat_in =~ /RedHat/) { @list = ("/etc-test/resolv.conf", "/etc-test/sysconfig/network-scripts/ifcfg-$nic_device_in +"); } return @list; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://821596]
Approved by starX
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2024-04-20 02:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found