in reply to Re^6: Module Announcement: Perl-Critic-1.01 ("scalar")
in thread Module Announcement: Perl-Critic-1.01
If you have a function that always returns exactly one item (as the list of items that it returns), then it doesn't make sense to change this function to return a zero-item list in one special case.
That's not what return; does. It returns something that's false in boolean, scalar, and lists contexts. I know you know this; it just seems valuable to be very explicit about what we're discussing.
Now (on topic), it's difficult for Perl::Critic to recognize the semantic need for that with regard to any single specific Perl function. It seems like a variant of the semi-predicate problem; what does return undef; mean?
Damian's rule is Use a bare return to return failure. I believe that's good advice.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^8: Module Announcement: Perl-Critic-1.01 (failure)
by tye (Sage) on Jan 27, 2007 at 03:59 UTC | |
If you have a function that always returns exactly one item (as the list of items that it returns), then it doesn't make sense to change this function to return a zero-item list in one special case.That's not what return; does. return; doesn't return a zero-item list? Yes it does and I know you know this. It returns something that's false in boolean, scalar, and lists contexts. I don't think there is a such a thing as "false in list context". The advantage of return; is that it makes a list assignment false (and that it makes an array that you assigned the return value to false). But I don't find myself doing such types of assigning a scalar to a list in a boolean context and when I consider that, I find it unnatural. I don't find it unnatural to write:
Where "foo" and "bar" are each the type of thing represented by a scalar value and one might fail to do "foo" or fail to get "bar". And it is convenient to be able to place in a scalar something that represents "oops, we failed to get this value" and that is why Perl has undef and I see no problem with using return undef; to represent a failure in a function that returns a scalar value (or to use return ''; to indicate failure in a fucntion that always returns a non-empty, true string value -- especially since it avoids gyrations to avoid "use of uninit val" warnings). Damian's rule is Use a bare return to return failure. I believe that's good advice. And I agree with that advice up to the point where you have a function that has always returned one scalar value in every other situation. I think I've covered rather thuroughly why I believe that. If the function usually returns just a scalar but sometimes doesn't, then I'd err on the side following that advice. In another reply you write: for those functions where their return value should be unambiguously false when it's false And I find that return; breaks that very rule in quite natural code such as the above followed by:
or natural code like:
Your advice would give us "bar" (which isn't false) after doFoo() failed. And I realize that when I write %hash= ( key => ... ) that "..." needs to be a scalar and so if someFunc() returns a list (that might have other than 1 element) then I need to write one of:
But I would find it very unnatural to add to my mental model "if someFunc(), which is meant to return just a scalar, might want to return a failure indication then I have to put scalar() in because a failure indication can't be a scalar value (according to Damian)". - tye | [reply] [d/l] [select] |
|
Re^8: Module Announcement: Perl-Critic-1.01 (scalar)
by BrowserUk (Patriarch) on Jan 27, 2007 at 03:56 UTC | |
Now (on topic), it's difficult for Perl::Critic to recognize the semantic need for that with regard to any single specific Perl function. Halleluyah!And that is the very essence of my aversion to Perl::Critic. You cannot (yet, and probably never) replace the human mind with a set of rules that can be interpreted and applied by a machine. When PBP was published, we could read it, take the arguements for each guide line on board; and then apply them subject to our own logic, reasons and emotion. For PHBs to enforce a 'Must comply with PBP' edict, they would have to read the book; read every line of code; and then make their arguments subject to both their own and the coders reason. The existance of Perl::Critic has now puts the tool in the hands of the PHBs to enforce the edict without the intervention of human reason. And that is always a bad thing. Imagine a world where human beings where unable to apply their reason and discrimination to rules and guide lines. You're working in one of those huge skyscrapers. A guy steps out of the lavatory having forgotten to zip his fly. He is seen by a cow-orker and that person hits the alarm button. Five or ten thousand people are evacutated to the carpark in the pouring rain for 2 hours whilst the local emergancy service respond to the alarm, verify the safety of the entire building and certify it safe for the workers to reoccupy. Thousands of people get wet; hundreds of customers get frustrated; dozens of companies take substantial financial hits; because no discrimination was applied to the situation. Ridulous you say. It would never happen. But that is exactly analogous to the absence of a particular RCS markup; the absence of an explicit package statement in a program (as opposed to a module); and 90% of the other 255 guidelines in PBP--when applied without descrimination. Yes, Perl::Critic can be applied with optional, discriminatory configuration. But if the default is for no discrimination, then it will become the defacto standard. Just as I feared it might when I first saw the module. There has to be discrimination between those practices that can genuinely lead to errors, bugs, or even simple misunderstandings; and those that are simple preferences--desirable in certain places, at certain times, on certain projects. The example above is proof by reduction to absurdity, but lets try something a little less absurd. The same scenario, but this time the problem is a laptop who's battery has gone open ciruit and is starting to smoke. You could hit the fire alarm with a similar result to the above. Or, you could walk over, unplug the charger from the mains and flip the battery eject lever. You might also use a pencil to slide the hot battery into an empty metal waste bin. Is it safe to take the latter course? It depends upon the circumstances--and that's where human reason and discrimination come in. That might sound like a contrived example, but it's very close to a real life situation, though I only know of it through hearsay. The person chose to take the latter action, with the addition of discharging a CO2 fire extinguisher into the waste bin to cool the battery down. He was formaly rebuked for not setting off the fire alarm and forcing a couple of thousand people from more than a dozen financial services companies from spending a couple of hours in the rain! Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] |
by chromatic (Archbishop) on Jan 27, 2007 at 06:45 UTC | |
I seem to get by okay saying no strict 'refs'; once in a while, though you know as well as I do that people here holler if they don't see the always mandatory without questions asked strict and warnings pragmas in code. I'm really struggling to see how the existence of a tool and the existence of ignorant people who will use it badly suddenly means that the tool itself is a bad idea. | [reply] [d/l] |
by BrowserUk (Patriarch) on Jan 28, 2007 at 05:39 UTC | |
I'm really struggling to see how the existence of a tool and the existence of ignorant people who will use it badly suddenly means that the tool itself is a bad idea. Ignorant people exist in all fields, and tools will always be used badly. The trick is to make tools as safe as possible, by default, without rendering them so annoying as to discourage the use of their safety features. A while ago, I came up with this analogy to demonstrate that being pro-choice does not have mean that one is anti-safety. However, when a motoring journalist reviewed the BMW M5, he noted that whilst the four-dour saloon (sedan) is spec'd as capable of achieving sub 5-second 0-60mph times; that the 11-way Driving mode selections combined with ultra-conservative default setting and the complexity of the selection process itself, meant that it took someone very familiar with the systems, longer than 5 seconds simply to switch the vehicles electronics into the appropriate mode required to achieve it. His conclusion was that the vast majority of owners would either permenantly enable the highest performance setting and so forgo the safety features for the great majority of the time when the simply did not need the extra performance, in order that it should be available when they did. Or, they would never switch it away from the default setting and so the extra 25% of power it affords would never be used. The same journalist had this to say about the (then) latest Corvette. The Americans lecture the world on democracy and then won't let me turn the traction control off! The point is, if the default settings are left at the highest, most pendantic and annoying setting (as with the web page); or if the complexity of tailoring the setting is horribly complex and an inappropriate level of default is chosen, then those who could most benefit from it will ignore it if they can (vis. the number of people who come here not using strict because it makes their lives harder!). And for those (PHBs) who have no real interest in understanding the complexities of the configuration, nor the arguments behind the choices they allow, will simply opt for an ass-covering "All code must comply with the default settings" edict. Maybe you've always been lucky enough, or choosy enough to work places where management is drawn from the ranks of the technically informed, but very few programmers are so lucky. If you have had to work under the edicts of uninformed, Business Degree Only management types as I have on several occasions, then you'll know that defacto standards come about by accident, rather than good decision making, in the vast majority of cases. Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] |
by rir (Vicar) on Jan 29, 2007 at 04:32 UTC | |
I stopped using Perl because it would not scale up to the tasks I was addressing. Then the strict pragma was created; that automatic application of a set of contraints to code was helpful. The many real mistakes caught were well worth the few false positives. In the general case, it is foolish to assume that bosses are morons and underlings have the correct answers. A consortium of underlings may conspire and through insubordination save a project from a mandate of some stupid practice, but that just helps to prove the mandate worthwhile when a review is done. That there are 256 Perl best practices is just too cute.
Be well, Update: Added when a review is done because the sentence could be read with either of two opposing meanings. | [reply] |
by BrowserUk (Patriarch) on Jan 29, 2007 at 05:35 UTC | |
In the general case, it is foolish to assume that bosses are morons and underlings have the correct answers. First, there is no implicit or implied assumption that all bosses are morons. Having been the boss for a good part of my career, that would indeed be foolish. I've also been lucky enough to work for many, very excelllent bosses over the years. However, I've also been unlucky enough to work for some, who whilst often very competent people and resource managers, decisions makers etc., that were completely out of their element when it came to the technical issues of the departments they ran. These are far more common than one would like, and it's not always a bad thing. The problems arise when they start to make technical descisions in ass-covering mode; or on the strength of the school/college/regimental logo on the tie of the last salesman they spoke to; or the quality of the meal he brought them; or simply because his sales pitch had convinced them that XYZ would save their project. A consortium of underlings may conspire and through insubordination save a project from a mandate of some stupid practice, but that just helps to prove the mandate worthwhile. No matter how I read that I would paraphrase it as: A mandate of a stupid practice is worthwhile, if it causes the underlings subjected to it, to pull together to save the project. Even if that means they must resort to insubordination to do so. Hmm. If a bad commander's policy of 'shoot to kill' eventually causes his troops to rebel and initiate a coup against him, his brutality was justified? Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] |
by rir (Vicar) on Jan 29, 2007 at 20:41 UTC | |
|
Re^8: Module Announcement: Perl-Critic-1.01 (scalar)
by jettero (Monsignor) on Jan 27, 2007 at 03:10 UTC | |
Suggesting that all functions have to return success or failure — just in case someone tests it in an list context — seems just a little myopic. Although, I don't think I say it nearly as well as tye (ie: {left => $dood->query_weapon(0), right => $dood->query_weapon(1)} ), so I probably should have just left it alone. -Paul | [reply] |
by chromatic (Archbishop) on Jan 27, 2007 at 06:41 UTC | |
Suggesting that all functions have to return success or failure — just in case someone tests it in an list context — seems just a little myopic. I agree. When did I suggest otherwise? I believe I have been consistent in implying (if not outright saying, which is probably my mistake here) that it's functions that do return either success or failure that ought to watch for list context. | [reply] |