Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Re: Re: What is this can() and why is breaking it (un)acceptable?

by tilly (Archbishop)
on Apr 06, 2004 at 19:19 UTC ( #343083=note: print w/replies, xml ) Need Help??

in reply to Re: What is this can() and why is breaking it (un)acceptable?
in thread Why breaking can() is acceptable

And you've just illustrated where I think that can() can be problematical.

Despite your claimed guarantee, you didn't guarantee that Net2::Server (or some subclass thereof) won't someday implement a method named foo() that does something radically different from bar(). And then your code will break.

The problem is that it is as much an abuse of an API to assume that a particular method will never be implemented as it is to use an internal one which may change. Also related is that it is a mistake to assume that what you'd think that foo() should mean will be what someone else will think. This is true even for such obvious values of foo() as a constant named PI. Is that a number or a Unicode character? This related mistake is a meta-problem with can().

Instead the right way for you to do that is to have some compatibility layer which guarantees that the interface that you want will be supported. That layer could be something as simple as a hash that says that method X is provided by package Y under name Z. Or you can actually implement a class which proxies the methods that you are interested in (incidentally giving you somewhere to put utility methods that one base class has and the other doesn't).

Now you don't have to worry about the API of Net2::Server changing on you, and you don't need to call can().

  • Comment on Re: Re: What is this can() and why is breaking it (un)acceptable?

Replies are listed 'Best First'.
Re: Re: Re: What is this can() and why is breaking it (un)acceptable?
by dragonchild (Archbishop) on Apr 06, 2004 at 19:30 UTC
    So, to summarize what it is I think you're getting at:

    can() doesn't really serve any useful purpose.

    1. It doesn't really provide usefulness as an interface validator (because interfaces change and because of AUTOLOAD)
    2. Its secondary function of providing a coderef doesn't help, because of AUTOLOAD and because of the questionable use of this

    So, why does it exist?

    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      What I want to get at depends on your programming style. Let me first give some perspective.

      If you are good about having really clear function names, then in practice nobody is actually going to name a function something that will conflict with the name that you look for. In that case, if can() finds the method, it is a reasonable assumption that the method will, in fact, do what you expect it to. Furthermore if you are good about not using AUTOLOAD, or else using AUTOLOAD and overriding can() and being aware of where your override works, then it is reasonable to assume that can() does what it should do.

      In that case there are lots of interesting design patterns that use can() for reflection. Which is why enough people consider it useful that it got put in the core.

      If, however, either of the assumptions is wrong, then its utility drops rapidly. It is fine in cases where you check that it works, but it will be a fragile layer. (Depending on your perspective you can blame the fragility on can() itself, or on the practices that made can() fragile. It doesn't really matter - the fragility is there.)

      Furthermore there are other styles of programming in which you are very unlikely to want to reach for can() at all. Therefore an erosion of can() is going to not matter to you.

      If you're in the first camp, people who want to reach for can() whose own personal style is going to make it work out for you, then people who casually break can() are going to frustrate you. I would like you to understand the perspective of people who are going to break can(), and be aware of why it is unrealistic to expect them to generally improve and start working like you want them to work.

      If you're in the second camp, people who are likely to accidentally break can(), I want you to understand what the issue is, why it becomes an issue, and have enough perspective to more deliberately make the decision about whether or not YOU will choose to support can() in any particular scenario.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://343083]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (8)
As of 2017-07-26 07:51 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (385 votes). Check out past polls.