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

Two questions:

First, the easy one... In the following, what looks better to you for subroutine names?

our @EXPORT = qw(linux_add_account sun_add_account hp_add_account aix_add_account);
OR
our @EXPORT = qw(LINUXAddAccount SUNAddAccount HPAddAccount AIXAddAccount);

Question 2:
I have subroutines (see above) that have OS type in them. I use another subroutine to get os type ( my $foo=get_os_type($server); ), and then I call the subroutine (at this point) like so &$varAddAccount. I cannot use strict subs and do this, but that is not an option here. I want to use strict, but do not know how to call the subroutine based on what is in var, without having a bunch of if statements all over the place (or switch). Any ideas? I call many different subroutines based on os type, all over the place (e.g., SUNAddUser, SUNDelUser, SUNGetStatus...).

Replies are listed 'Best First'.
Re: Call Subroutine with Variable
by Your Mother (Archbishop) on Jul 31, 2009 at 05:16 UTC

    For the first half-

    our @EXPORT = qw(linux_add_account sun_add_account hp_add_account aix_add_account);

    It is Perl standard and generally easier on the eyes. Plus you don't end up with ambiguous, randomly cased bastards resulting from case collisions like IDXML, IdXML, IdXml, pHURI, PHURI, pHUri, etc, and so on and so forth.

Re: Call Subroutine with Variable
by GrandFather (Saint) on Jul 31, 2009 at 06:03 UTC

    Light weight OO is a neat solution for this. Consider:

    use strict; use warnings; my $obj = bless {}; my $verb = 'AddAccount'; for my $os (qw(SUN HP XP)) { my $sub = $obj->can ("${os}AddAccount"); if (! $sub) { print "Don't know how to $verb for $os\n"; } else { $sub->($obj); } } sub LINUXAddAccount { my ($self) = @_; print "Linux goes moo\n"; } sub AIXAddAccount { my ($self) = @_; print "AIX goes moo\n"; } sub HPAddAccount { my ($self) = @_; print "HP goes moo\n"; } sub SUNAddAccount { my ($self) = @_; print "SUN goes moo\n"; }

    Prints:

    SUN goes moo HP goes moo Don't know how to AddAccount for XP

    Note that all you need do to support XPAddAccount is add the sub - no tables to update or any other code changes required.


    True laziness is hard work

      If you're using OO, go the whole way and use polymorphism. Create a subclass for SunOS, one for HPUX, one for XP, one for Linux, and then call add_account on each object.

      I like this!!

      Just one question, how would I call the sub with parameters? Like if I wanted it to say "AIX goes $what\n";, how would I send the $what to the subroutine... I hope that makes sense.
        perlboot
        BEGIN { package Foo; sub new { return bless {}, shift } sub method { my( $self, $what ) = @_; print "AIX goes $what\n"; } } my $obj = Foo->new; $obj->method('the what'); __END__ AIX goes the what
        perlsub
Re: Call Subroutine with Variable
by CountZero (Bishop) on Jul 31, 2009 at 05:57 UTC
    For the second half, you want to have a look at Dispatch Tables. The incomparable Higher Order Perl - Chapter 2 will explain you all.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Call Subroutine with Variable
by doug (Pilgrim) on Jul 31, 2009 at 16:14 UTC

    I prefer constants to be all caps, OO Classes to be mixed, and pretty much everything else to be all lower. Maybe more caps for global data, but generally speaking I avoid it.

    Regardless of case, that is a horrible mismatch. SUN and HP refer to companies, and AIX refers to an OS from IBM. I guess Linux could go either way The hobgoblins in my mind would like some consistency here. I'd go with OS over company (ie Sun => Solaris, HP => HP-UX) but that is your call.

    As for question #2, why not simply add_account($server) and have that call get_os_type()? Doesn't this solve the problem by only exposing a single prototype that works for all OS types?