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

Checking for duplicate subroutine names

by SirBones (Friar)
on Oct 12, 2012 at 15:32 UTC ( [id://998725]=perlquestion: print w/replies, xml ) Need Help??

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

Hello; as usual I humbly admit my lack of Perl knowledge and ask for your kind assistance. I have tried the documentation but nothing leaps out at me.

I have observed that the following (poorly styled code, duplicate subroutine names and all) compiles and runs just fine:

#/usr/bin/perl -w use strict; sub s1 { print "hi\n"; } sub s1 { print "hi 2 you\n"; } print "calling s1...\n"; s1();

OK, that seems to run the second "s1()".

Cut to a fairly large "command processor" I developed to send individual test control statements from a simple prompt to some machines we run. One of the options I have added to this tool is the ability for users to define their own Perl subroutines in an external file, and then issue a command to "include" that file in the test control tool. I suck this file in via a "require", and then the user can issue his own customized commands running his own Perl code. Works great.

My dilemma is: The base tool has dozens of subroutines, and I fear that a user will inadvertently define a sub with the same name as one of my base ones. This could be a Bad Thing. I had originally thought Perl would yell at me when I tried to "require" such a file, but apparently Perl does not mind duplicate subroutine names (thus my example above.)

I could solve this by keeping a list of all my subroutine names and then comparing them with the ones the user proposes and refusing to load his file if I pick up a duplicate. But I was wondering (out of laziness) if there was already a way for Perl to pick up on this and flag a problem on the fly, without my having to write a checker procedure.

Thanks muchly (as usually).

-Ken

"This bounty hunter is my kind of scum: Fearless and inventive." --J.T. Hutt

Replies are listed 'Best First'.
Re: Checking for duplicate subroutine names
by VinsWorldcom (Prior) on Oct 12, 2012 at 15:45 UTC
    use warnings;

    I'm not a Perl expert either, but -w and 'use warnings' apparently aren't the same:

    VinsWorldcom@C:\Users\VinsWorldcom\tmp> test.pl Subroutine s1 redefined at C:\Users\VinsWorldcom\tmp\test.pl line 9. calling s1... hi 2 you

      Thank you. I was not aware (or had forgotten) that the -w switch was not identical to "use warnings". That gets it alright.

      -Ken

      "This bounty hunter is my kind of scum: Fearless and inventive." --J.T. Hutt
Re: Checking for duplicate subroutine names
by flexvault (Monsignor) on Oct 12, 2012 at 16:05 UTC

    SirBones,

    Look at the use of 'package'. I believe that all variables and subroutines are defined by package.

    One way to do what you want is name your code as 'package something.pm'. Since your using require to bring the script into your main package, load your package via 'use' at the beginning of execution, and then loop on the require part which will include calls to your subroutines for building the user's script. I would also put the loop in an 'eval'.

    Other Perl Monks will have more experience with 'package' (hint: you need it for CPAN). I've only used it once or twice.

    Good Luck

    "Well done is better than well said." - Benjamin Franklin

Re: Checking for duplicate subroutine names
by kcott (Archbishop) on Oct 12, 2012 at 20:20 UTC

    G'day Ken,

    Unfortunately, that rather sounds like a disaster waiting to happen. What if a user defined a custom subroutine like this:

    sub generate_monthly_report { `rm -rf *` }

    You may have already considered this sort of thing; however, it raised a red flag in my general direction so I'm just waving it back at you.

    -- Ken

      Yes, absolutely understood. We are assuming a group of very local and trustworthy users; their jobs are on the line. ;-)

      Cheers,

      -Ken

      "This bounty hunter is my kind of scum: Fearless and inventive." --J.T. Hutt
        Um... not a good assumption.

        What happens when one of them becomes disgruntled; is given notice; or the like?

        Oops. Bye bye who knows what.

        ... and what happens, someday in the sweet bye-and-bye when the powers-that-be decide your code creates a business opportunity to be shared with customers?

        [ sounds of gnashing of teeth; rending of flesh....]

        Please don't do it that way.

        My original example certainly suggests blatant maliciousness on the part of some user; however, the most trustworthy of employees, with the best intentions in the world, can write some apparently innocuous code which could have severely adverse side effects.

        Consider a user-supplied subroutine which simply reads some data (e.g. get_stock_count()). What happens if that code is called while some system function (e.g. update_stock_count()), which has been running successfully for years with no ill-effects, is in the process of being run? Is the read statement of get_stock_count() executed before or after the write statement of update_stock_count()? What are the implications of this?

        [Here's a potential scenario. Supplier (on the phone to User): "Is it a problem if those parts aren't delivered today?". User (after running get_stock_count()): "I've checked the stock count - we've got plenty - next week will be fine.". Production Manager (screaming at Senior Programmer the following day): "The manufacturing plant has ground to a halt. You're responsible for stock count data. User told me he ran code approved by you that reported an adequate supply. Tell me why I shouldn't sack you!"]

        My recommendation would be that any user-supplied code goes through the same process of quality control (review, testing, etc.) that you'd expect to apply to your own code.

        -- Ken

Re: Checking for duplicate subroutine names
by mbethke (Hermit) on Oct 12, 2012 at 17:22 UTC

    What flexvault said: you should be safe from accidental overwriting if you put your functions in a separate package. However, you still have to trust your users not to do Evil Things---as far as I know there's no way to write-protect a namespace so even an ill-intentioned user can't screw with your code.

    Edit: actually it's not "package something.pm" but "package Something", conventionally in a file called "Something.pm". User package names should not be all-lowercase.

Re: Checking for duplicate subroutine names
by flexvault (Monsignor) on Oct 13, 2012 at 09:51 UTC

    Dear Monks,

    My recent use of most modern web-servers is that they don't let you go outside of the 'DocumentRoot'. So your users may wipe out your code, but they can't touch the system.

    But for additional safety you could use a web-server that is running in a chain root directory (see 'chroot') under a low priority user:group. Malicious or not, *nix is not going to let someone out of the new root of your/their file-system.

    "Well done is better than well said." - Benjamin Franklin

Re: Checking for duplicate subroutine names
by clueless newbie (Curate) on Oct 17, 2012 at 11:27 UTC

    Two CPAN modules come to mind Devel::Symdump and Module::Info (and its cousin Module::Info::File). Whereas Devel::Symdump doesn't discriminate between subs your module declares and subs exported into your module, Module::Info does.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (3)
As of 2024-03-29 06:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found