Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Allowing user to change module variables

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

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

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 = "http://standards.ieee.org/regauth/oui/oui.txt"; 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("http://standards.ieee.org/regauth/oui/oui.tx +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 <http://standards.ieee.org/regau +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 <mvaline@buffnet.net> =cut

Replies are listed 'Best First'.
(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.

    Cheers,
    Ovid

    Vote for paco!

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

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.)

(tye)Re: Allowing user to change module variables
by tye (Sage) 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";
    and
    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 = "http://standards.ieee.org/regauth/oui/oui.txt"; $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?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2024-04-19 22:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found