Beefy Boxes and Bandwidth Generously Provided by pair Networks DiBona
Perl-Sensitive Sunglasses

Allowing user to change module variables

by mvaline (Friar)
on Jul 18, 2001 at 23:49 UTC ( #97858=perlquestion: print w/ replies, xml ) Need Help??

As per advice given to me in Find Ethernet Card Manufacturer, I've created my first real module. My module mirrors a copy of a remote file the location specified in my module's variable $oui_location. I would like the script that uses my module to be able to change that value.

I tried including $oui_location in the @EXPORT_OK array and then doing something like this in the calling script:

use OUILookup ('get_oui_owner', 'oui_location'); $oui_location = "oui2.txt";

but it didn't work.

What do I have to do?

package OUILookup; require Exporter; use LWP::Simple; use strict; use warnings; our @ISA = qw(Exporter); our @EXPORT = qw(get_oui_owner); our $VERSION = 1.00; my $oui_address = ""; my $oui_location = "oui.txt"; sub get_oui_owner { my ($mac) = @_; my $oui = validate_input($mac); my $oui_entry; my $foundit = 0; if ($oui eq "invalid address format") { return $oui; } else { if (update_ouidb()) { open(OUI, $oui_location) or die "Unable to locate $oui_loc +ation: $!\n"; while (<OUI>) { chomp; if (/$oui/) { $oui_entry = $_; $foundit = 1; last; } } close(OUI); if (!$foundit) { return "OUI not found"; } else { $oui_entry =~ s/\w{2}-\w{2}-\w{2}|^\w{6}//g; $oui_entry =~ s/\(hex\)|\(base 16\)//g; $oui_entry =~ s/^\s+//g; return $oui_entry; } } } } sub update_ouidb { my $errcode = mirror(" +t", $oui_location); if (!($errcode eq "200" || "304")) { die "problem updating OUI database: $!\n"; } else { return 1; } } sub validate_input { my ($input) = @_; my @bytes; my $oui; if ($input =~ /\w{2}-\w{2}-\w{2}-\w{2}-\w{2}-\w{2}/) { @bytes = split '-', $input; $oui = join '-', $bytes[0], $bytes[1], $bytes[2]; return $oui; } else { return "invalid address format"; } } 1; =head1 NAME OUILookup =head1 SYNOPSIS Find the owner of the IEEE Organizationally Unique Identifier (OUI) for a particular MAC address. OUILookup uses the IEEE database from < +th/oui/oui.txt>. It will create a local copy of that database if one does not already e +xist, and update a the local copy if it does exist. By default, the local copy will be stored as oui.txt in the same direc +tory as the script. This location is set by the module variable $oui_location. =head1 USAGE use OUILookup; $mac = "00-10-5A-1B-C3-30"; $owner = get_oui_owner($mac); =head1 REQUIRES LWP::Simple =head1 TESTED Perl 5.6.0 on Windows NT (Service Pack 6) =head1 AUTHOR Micah Valine <> =cut

Comment on Allowing user to change module variables
Select or Download Code
Re: Allowing user to change module variables
by dragonchild (Archbishop) on Jul 18, 2001 at 23:55 UTC
    $OUILookup::oui_location = "blah"; will work if the variable wasn't declared with my.

    Of course, it's better to have a function called set_ouilocation() to do it for you. Just a thought.

      Ah, of course I should have such a function. I'll do that.

      With regard to the first solution... would our be the correct scoping keyword to declare my variable with it? I can't just declare it or use strict barks at me.

        strict complains if it has either no scoping or a scoping of local. my gives you nice, neat lexical scoping. our gives you a funky lexically-scoped global-type-thingy which I'm not fully conversant with, but works relatively well.

        If you're going to create a function to get/set this variable, do something like:

        my $var = 0; sub get_var { return $var; } sub set_var { my ($new_val) = @_; # Do some checks on $new_val here. $var = $new_val; return $var; }

        The reason you have it scoped with my is to keep it protected as much as possible from accidental clobbering.

        (Of course, you could just put yourself into that namespace, but that's just being silly.)

(Ovid) Re: Allowing user to change module variables
by Ovid (Cardinal) on Jul 18, 2001 at 23:59 UTC

    By declaring $oui_location with my, you've made it lexically scoped and unavailable to your other packages. There are a variety of strategies to deal with this. This simplest is to change package OUILookup:

    $OUILookup::oui_location = "oui.txt";

    When other code references this variable, simply refer to it with a fully qualified package name. However, global variables are usually a bad idea. You could use Exporter:

    package Scrap::Foo; use strict; use Exporter; use vars qw/ @ISA @EXPORT $foobar /; @ISA = qw/Exporter/; @EXPORT = qw( $foobar ); $foobar = 7; sub doit { print $foobar; } 1

    Then, in package main, I have the following:

    use Scrap::Foo; use strict; $foobar = "Hello"; Scrap::Foo::doit;

    That will print "Hello" instead of 7.

    My suggestion, though, would be to create a set_oui_lookup() sub in your module. That's the cleanest solution.


    Vote for paco!


(tye)Re: Allowing user to change module variables
by tye (Cardinal) on Jul 19, 2001 at 20:38 UTC

    Just for completeness... Here is what works but that you probably shouldn't do:

    use OUILookup qw( get_oui_owner $oui_location ); $oui_location = "oui2.txt";
    package OUILookup; use strict; use warnings; use base qw( Exporter ); use LWP::Simple; use vars qw( @EXPORT @EXPORT_OK $VERSION $oui_address $oui_location ); BEGIN { @EXPORT= qw(get_oui_owner); @EXPORT_OK= qw( $oui_address $oui_location ); $VERSION = 1.00; $oui_address = ""; $oui_location = "oui.txt"; }
    That is, ex/importing 'x' is the same as eximporting '&x' so to export a variable you have to include the '$', '@', or '%' in both the @EXPORT/@EXPORT_OK and the use line.

            - tye (but my friends call me "Tye")

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://97858]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (2)
As of 2014-03-16 13:45 GMT
Find Nodes?
    Voting Booth?

    Have you used a cryptocurrency?

    Results (326 votes), past polls