Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Built-in Function Homonyms for Method Names Bad, Too?

by jffry (Hermit)
on Jan 25, 2006 at 22:36 UTC ( [id://525588]=perlquestion: print w/replies, xml ) Need Help??

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

I know that, in most cases, subroutines should not be named after built-in functions. Makes perfect sense to me. However, what about method names?
my $newobj = My::Class->new(); $newobj->return(); $newobj->split(); $newobj->delete();
Is this also bad practice? I think the answer is, "Yes this is bad. Don't do it." But I would like a consensus, because I'm not as certain as I'd like to be. I may even reverse my opinion if given good reason.

The reason I ask is that I just noticed that vim was highlighting one of my method names different from all the rest. Turns out it was a Perl built-in name, also. Oops!

Replies are listed 'Best First'.
Re: Built-in Function Homonyms for Method Names Bad, Too?
by hv (Prior) on Jan 26, 2006 at 00:01 UTC

    I see nothing wrong with it as long as the names are appropriate in the context of the class. My work application has delete (for the SQL sense) and bless (for the Perl sense) supplied by the database abstraction, and other areas offer warn, die, open, close, log, format, umask, stat, send, ref and link.

    And that's just the explicit ones: there are probably many more keywords used as fieldnames in the database which get autogenerated accessors of the same name.

    The fact that they are also keywords has not caused any problems for me in the 4-5 years of using them, nor (to the best of my knowledge) for my colleague.

    I don't use a syntax highlighter though. :)

    Hugo

      Hmmm. That's a pretty convicing testimonial. At this point, I think I'll save myself the work of renaming the method in question, and see how it goes. From your experience, it looks like I'm pretty safe.

      Thanks, all, for the input so far!

        I personally see it as a source of ambiguity and difficult to predict bugs. What if you define return() within a package, to be used as an object method, but then within the class itself one of the subs uses return()? Which return() will be called, the package one, or the core one? I had to test to find out (in my simple test, the core routine got called). I see it as an unnecessary source of potential mistakes.

        Can you be sure that at some point down the road one of those overloaded names won't be invoked with the expectation of getting one behavior but with the result of getting the other behavior? I know there are hard and fast rules governing such things, but it's easier to just avoid the issue in the first place.


        Dave

Re: Built-in Function Homonyms for Method Names Bad, Too?
by Old_Gray_Bear (Bishop) on Jan 25, 2006 at 23:55 UTC
    I'd much less troubled by method names in collision with builtins because of the visual difference between them:
    $self -> split();
    The presence of the 'object->' lead-in is a direct cue that this isn't the Perl builtin split()....

    ----
    I Go Back to Sleep, Now.

    OGB

Re: Built-in Function Homonyms for Method Names Bad, Too?
by duff (Parson) on Jan 25, 2006 at 22:53 UTC

    I don't think it's a bad practice. You should name your methods such that they make sense in light of the problem your trying to solve and how you will use your object regardless of whether or not those names happen to conincide with perl built-ins.

      Well, there are plenty of decent synonyms I could use for method names instead. So that point is covered in my case.

      I guess the tough question is: if I keep using these homonym method names is there some Perl syntax parsing nightmare I'm going to hit at some point.

      OR

      If you (plural) can't cite specific examples of Perl parsing dangers, is the threat of such dangers enough for me to not use homonyms.

        I guess the tough question is: if I keep using these homonym method names is there some Perl syntax parsing nightmare I'm going to hit at some point.

        Short answer is, if you're always calling methods with ->, then there won't be a problem. Parsing problems only come about when your in a place where a built in can live, and after -> isn't one of those places.

        Personally I'm for using homonym method names when they make sense, since if they're used appropriately you already "know" what they do.

Re: Built-in Function Homonyms for Method Names Bad, Too?
by rinceWind (Monsignor) on Jan 26, 2006 at 12:24 UTC

    There's one gotcha that others haven't mentioned, which is an issue for you, the module author, rather than for those using your module.

    The gotcha is that any attempts to use the builtins inside your module: return, split, delete, will result in calls to the subs in your package, not the builtins (and they will probably fall over as they are expecting an object as $_[0]). To get the real builtins, they now need to be qualified, viz: CORE::return, CORE::split and CORE::delete.

    Care is needed coding your module, as this is a source of bugs.

    --

    Oh Lord, won’t you burn me a Knoppix CD ?
    My friends all rate Windows, I must disagree.
    Your powers of persuasion will set them all free,
    So oh Lord, won’t you burn me a Knoppix CD ?
    (Missquoting Janis Joplin)

      The gotcha is that any attempts to use the builtins inside your module: return, split, delete, will result in calls to the subs in your package, not the builtins [...]

      I can't find a test case for this behaviour - do you have an example?

      There is a distinction between strong and weak keywords 1 which shows a slight difference in behaviour. With a strong keyword, the keyword overrides the subroutine:

      zen% perl -wle 'my %hash; sub delete { die "not this one" } delete($ +hash{key})' zen%

      A weak keyword gives a warning, but is still preferred to the subroutine:

      zen% perl -wle 'sub bless { die "not this one" } my $a=bless({});' Ambiguous call resolved as CORE::bless(), qualify as such or use & a +t -e line 1. zen%

      I'm sure I'm missing something that would justify your comment, but I can't offhand think what it is.

      Hugo

      1 The distinction between weak and strong keywords is probably not well documented; in older perls I think the only way to check was to examine the C code in toke.c, but happily perl-5.8.7 now bundle a script perl_keyword.pl to generate the code, which has clear lists of weak (@neg) and strong (@pos) keywords at the start of the script.

      Zoiks, Scooby! That scared me right back into avoiding homonym method names. At this point I've flip-flopped back, and I think I'll stay here on this side of caution. I'm changing 'em now while I'm still early in this project.

      Thanks, all, even to those who told me to leave 'em as-is, but my paranoia probably would have given me too much tension anyway.

        Remember, though, that polymorphism is one of the selling buzzwords of object-oriented programming: you can use the same method name on objects of a different class, and have it do different things. That's desired. (And yes, I know that "objects of a different class" and "builtins" don't equate, but in this case they overlap enough for the benefit to still hold.)

        Also, although this means you need to be a little more cautious in your module, remember that the whole point of creating a module is so that it will get re-used. A little burden up-front is (presumably) worth it in the long run. If a dupe of a built-in name makes the most sense to you, it will probably be easy to remember (and therefore easy to use) for your clients as well.

Re: Built-in Function Homonyms for Method Names Bad, Too?
by jffry (Hermit) on Mar 04, 2006 at 22:48 UTC

    An update on this debate.

    I have decided to avoid homonym method names. Well, I just spent 2 hours trying to figure out a bug that was caused by almost exactly this problem. I am using Object::InsideOut, and I was writing a module/Class for locking. So, of course, you can set locks, right? So in my calling code I have:

    my $lock = My::Lock->new(blah => blah); $lock->set();

    Well, I forgot about OIO's ->set() Class method that is used for setting attributes inside class code. And, of course, I'm using that exact Class method inside a private method in Lock.pm which is itself called by my regular public method ->set(). So, of course, I've got a recursion nightmare. Add to that I accidentally had my $self = @_; instead of my $self = shift; for that private method, and man do you have a puzzler.

    So I was unintentionally overriding a Class method in the same class that I was counting on using the parent level method. All with a scalar return context problem for the object ID to throw me off even more.

Re: Built-in Function Homonyms for Method Names Bad, Too?
by Moron (Curate) on Apr 18, 2007 at 20:34 UTC
    There are core modules that deliberately use the same name as a built-in they emulate. For example, Filehandle's open method.
    __________________________________________________________________________________

    ^M Free your mind!

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2024-04-25 06:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found