Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re^6: ref to read-only alias ... why? (notacrisis)

by LanX (Canon)
on Jan 06, 2012 at 19:55 UTC ( #946656=note: print w/ replies, xml ) Need Help??


in reply to Re^5: ref to read-only alias ... why? (notacrisis)
in thread ref to read-only alias ... why?

> less fragile interface to the sub

We showed that any call-by-reference can be affected.

So you are effectively saying that modifying $_[ ] is a fragile interface and bad coding practice?

I agree it's not a crisis, but this must at least be documented, not only for helping people desperately trying to understand the reason why an imported sub using another imported sub fails out of a sudden, because an alias was passed thru the chain.

This can't be avoided, even less if people use Data::Alias or Lexical::Alias.

UPDATE:

> I'd rather just add an eval to the code

And how do you expect eval to help if there is no error thrown?

Cheers Rolf


Comment on Re^6: ref to read-only alias ... why? (notacrisis)
Download Code
Re^7: ref to read-only alias ... why? (eval)
by tye (Cardinal) on Jan 06, 2012 at 22:34 UTC
    We showed that any call-by-reference can be affected.

    That's an overstatement. The only thing that can be impacted is a sub that tries to modify an alias and then gets passed a read-only value and where that situation isn't just declared a bug and gets fixed. So, yes, exactly as I said, the worst possible case can be solved by adding a simple eval around the code that modifies the reference but is (badly) designed to also tolerate the failure in the case of read-only parameters.

    but this must at least be documented

    So the standard Perl documentation absolutely must document that trying to modify an alias to a read-only scalar might fail if you try to modify it? Or is your point that it is imperative to document that it might not fail? The first case seems completely reasonable to expect from the existing documentation. The latter is quite an edge case and seems not particularly vital to document, especially since I predict that you'll have plenty of fun just getting such a documentation patch approved since you'll probably just trigger a protracted (or another abandoned) argument over whether the inconsistency is a real bug or not.

    UPDATE: And how do you expect eval to help if there is no error thrown?

    If no error is ever thrown, then nobody knows and nobody cares and there is nothing to fix. The expressed problem was that there was no error thrown one place but then an error was thrown someplace else. Once the problem is found, fix the problem. It is easy to fix such a problem (at least in a relatively stupid manner, i.e. eval). It is better to fix it by declaring it a bug where the constant got passed to a sub that was designed to modify its argument. Even better is to stop writing subs that modify their argument thanks to implicit aliasing instead of requiring a reference to the thing-to-be-modified to be passed in explicitly.

    Not only does changethis( \1 ) make the mistake much easier to spot, it also will cause such things to always fail. And this isn't the only reason to avoid modification via implicit alias. I'm not saying such should absolutely never, ever be used. But, yes, I've seen plenty of problems with it. It is, indeed, more fragile than being explicit. And given that somebody went and used this only-aluded-to sub in a way where a constant got passed to it, I strongly suspect that the interface to this sub is worse than just your average "modify one of your arguments" cases.

    Yes, it is nice when Perl can catch potential errors for you. But there are certainly limits to that. But I'll probably address that more directly in a separate reply.

    I don't see how mention of this in the documentation would have even been much help in this situation. The odds of such documentation being noticed and then causing the potential problem to be noticed before stuff was shipped seems miniscule to me. As for "helping people desperately trying to understand the reason why", I don't see how it could help in that case, either. It would only help after the source of the problem has already been well identified and then it only helps in allowing those involved to more quickly (we hope) accept that such is a subtle interaction and is not an out-right Perl bug (and I'm not convinced it would actually do that in this case anyway).

    If you want to avoid frustrating debugging, then I suggest that you stop doing fragile things. That's the main reason I avoid a lot of things that I've found to be more fragile than others over the years. But I suspect if you'd posted some of this code and I'd responded "You may not want to do that", that you would not have been quick to follow my advice (based on some prior conversations). Now you know some of the pain that I've felt over the years that has lead me to program in a "conservative" style. It is obviously still your choice. But this is exactly the kind of pain I try to avoid and sometimes try to help other people to avoid.

    I also don't use Data::Alias. Just FYI.

    - tye        

      > That's an overstatement. The only thing that can be impacted is a sub that tries to modify an alias and then gets passed a read-only value and where that situation isn't just declared a bug and gets fixed.

      ...

      > If no error is ever thrown, then nobody knows and nobody cares and there is nothing to fix.

      Wrong, as you can see from the code I posted, not only the sub is affected, but the intended side-effect (of altering the call-by-reference argument) is missing without warning.

      in continuation of Re^3: ref to read-only alias ... why? (not consistent)

      DB<111> $x=0; for ($x,0) { print; inc_b($_); print " -> $_\n"} 0 -> 1 0 -> 0

      > So, yes, exactly as I said, the worst possible case can be solved by adding a simple eval around the code that modifies the reference

      How is eval supposed to help here?

      > but is (badly) designed to also tolerate the failure in the case of read-only parameters.

      So in your opinion manipulating $_[0] is a bad design!?!

      Could you please post some code-examples to illustrate your point of view?

      Cheers Rolf

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://946656]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (10)
As of 2014-08-29 22:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (289 votes), past polls