|
Old IT books are the gift that keeps on giving - I have a book on VB6 performing sterling work as a monitor riser.
Slogans aren't solutions.
|
|
|
|
|
I currently have 7 programming related books doing duty as monitor/laptop stands at the moment. Web Programming with Rerl, VC++6, and a computer architecture textbook for the right monitor stand. My laptop stand stack consists of 3 old text books: C++ Algorithms, C++ Data Structures, Tanenbaum's Modern Operating Systems (2nd ed), and one classic i bought with my own money: Tufte's The Visual Display of Quantitative Data. My center monitor was something I was able to pick out as opposed to something already in the office and available; it has a proper adjustable stand.
Did you ever see history portrayed as an old man with a wise brow and pulseless heart, waging all things in the balance of reason?
Is not rather the genius of history like an eternal, imploring maiden, full of fire, with a burning heart and flaming soul, humanly warm and humanly beautiful?
--Zachris Topelius
Training a telescope on one’s own belly button will only reveal lint. You like that? You go right on staring at it. I prefer looking at galaxies.
-- Sarah Hoyt
|
|
|
|
|
Code books are like old T-Shirts, just can't seen to justify throwing them out!
New version: WinHeist Version 2.2.2 Beta I told my psychiatrist that I was hearing voices in my head. He said you don't have a psychiatrist!
|
|
|
|
|
My belly has made that decision easy.
|
|
|
|
|
I hear ya, am getting there myself!
New version: WinHeist Version 2.2.2 Beta I told my psychiatrist that I was hearing voices in my head. He said you don't have a psychiatrist!
|
|
|
|
|
As people prepare to evacuate their cubes they are cleaning out... I recently gained A UNIX System V book and a COBOL book.
|
|
|
|
|
can anyone point me to it? my search-fu is failing me.
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
|
Not the one I was looking for which is Multiple Return Statements - blog@CodeFX[^] but that's a good one as well.
thanks
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
Look like one of the reason people like me don't use C++ at all at work....
|
|
|
|
|
I think this thread would be more valuable, in the long run if it were in the C# language forum.
Yegor Bugayenko has some interesting views on this topic: [^].
cheers, Bill
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
modified 24-Jan-17 3:34am.
|
|
|
|
|
I disagree that this would be more valuable in the C# forum. This is not just a C# case, but has implications on the thought processes of developers in any OOP language as well as procedural languages.
As to Yegor's article, I have to admit that it's not very compelling. While he says that the features he wants don't exist in a modern OOP language, he then says "stick with one and try and look like pure OOP" without justifying why this is purer OOP (I would argue heavily that it isn't). Statements without clear arguments backing up the approach means that I'm more likely to ignore a proposal, especially as his argument completely fails to address issues such as cyclomatic complexity.
This space for rent
|
|
|
|
|
Hi, Pete,Pete O'Hanlon wrote: This is not just a C# case, but has implications on the thought processes of developers in any OOP language as well as procedural languages Of course, I agree, CP does not have, now, a popular, widely used, forum for such "generic" discussions; in fact, I think there is much more "value meat" in content where such design principles are salient in articles "grounded" in usage in specific languages, and frameworks.
I'd consider your recent articles here an "epitome" of exactly such design content grounded in real-world coding contexts.
The issue I bring up here is one I have "banged the drum" about many times: imho there is technical content, like this thread, that could very valuable for many CP users in the future ... if it were not "submerged" in the spate of the ever-overflowing Lounge collage of bonhomie, brain-farts, puzzles, rambles, etc.
Since there are forums designed for specific languages, here, which are very popular, my idea, based on sheer pragmatism, was to have a way to hoist this content out of the Lounge, put it on one of those forums, and, hopefully, enable further technical discussion.Pete O'Hanlon wrote: his argument completely fails to address isusues such as cyclomatic complexity. You can bet yor boots (... err ... jodhpurs ?) I and others here would like to hear your thoughts on cyclomatic complexity and the issue of when, and how, to "return" !
Finally, I linked to Yegor's blog post because it was cited in one of the other posts mentioned, and because I thought it would add a contrarian perspective to the discussion. I do not endorse Yegor's views.
Personally, I favor using explicit multiple 'returns, rather than "fall through" to one 'return.
cheers, Bill
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
|
|
|
|
|
I can't read the articles (company rule blocking Internet access) but I give my experience on the subject.
At first I believed - and wrote my code in such a way - that returning early from a function wasn't a bad choice because it allowed to avoid conditional execution of subsequent actions should one prerequisite not be met and because all in all it's faster: if something's already over then why execute other operations?
Then reality hit me hard:
1) Intermediate return points are easy to miss and lead to a waste of time during debug, as I'd have to set breakpoints on every return statement and as I said they are easy to miss;
2) Adding further logic that check complex conditions in order to decide the course of action requires more work as you'd have to substitute the clean return with the very same state variables that you'd have to use in case of a single point of exit;
3) Logging at the end of a function with the whole state of the operations is done extremely cleanly if there is one or only a few return points. The more exit points the more recaps you have to write... and that's redundance, with all the known problems it carries;
4) clean-ups!!! With the bare minimum of return points it's very easy to place the various free(), delete, WSACleanup, whatever you need: just before the return! If there are previous triggerable returns chance are that in those cases, which may be rare, the cleanups are not called. Hilarity ensues.
So while I'm not a taliban of single point of exit (sometimes they are the best choice) as of now I prefer going in that direction as my experience proved me that on the long run it's the most stable and observable pattern.
Take my two cents for what they are worth.
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
I'm a little different on that: I prefer to do all validation at the top of the method and if it fails, exit immediately.
For example:
DateTime dob;
if (!DateTime.TryParse(tbDOB.Text, out dob))
{
... report problem to user ...
return;
}
double itemPrice;
if (!Double.TryParse(tbItemPrice.Text, out itemPrice))
{
... report problem to user ...
return;
}
... The alternative to this is to nest the ifs:
DateTime dob;
if (!DateTime.TryParse(tbDOB.Text, out dob))
{
... report problem to user ...
}
else
{
double itemPrice;
if (!Double.TryParse(tbItemPrice.Text, out itemPrice))
{
... report problem to user ...
}
else
{
...
}
} Which starts to get the "meat" of the function pushed out well to the right, which I don't like at all.
Once you are into the main function, then yes: single entry, single exit is preferable if possible.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Validation usually ends the function right there, I was speaking of the core of the function. In the end, for uniformity, I often change validation too to a single poit of exit - but once the code is something like
int function(...){
bool condition_ok = true;
int returnvalue = ERR_OK;
if (condition_ok) {
if (failed) then {
condition_ok = false;
returnvalue = errcode1;
}
}
if (condition_ok) {
if (failed) then {
condition_ok = false;
returnvalue = errcode2;
}
}
...
return returnvalue;
}
Then for uniformity it comes very easy to add validation also in this form. Functions like this are usually hardware initialization, connections, communications with retries and manual error corrections...
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
Surely validation would be in its own class rather than inside methods doing other things? Single responsibility and all that?
var validator = new MyValidator();
if (validator.Validate(objectToValidate).IsValid)
{
}
return;
Ah, I see you have the machine that goes ping. This is my favorite. You see we lease it back from the company we sold it to and that way it comes under the monthly current budget and not the capital account.
modified 31-Aug-21 21:01pm.
|
|
|
|
|
NO NO NO NO. Each method is responsible of validating its input data. Always.
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
So there are never cases when you'd want to do the same validation in more than one place?
[Edit] You might find life easier passing objects and using something like FluentValidation
Ah, I see you have the machine that goes ping. This is my favorite. You see we lease it back from the company we sold it to and that way it comes under the monthly current budget and not the capital account.
modified 31-Aug-21 21:01pm.
|
|
|
|
|
The same validation in different places calls for a function - or method, it's the same - of course, this is just plain old code reusability. But every function should validate its input parameters and the data it has access to before using them, unless extreme circumstances (i.e a hyper fast customized SIMD function).
And that carries over to checking pointers for non nullity before using them alongside the use of exceptions (where supported) and so on.
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
den2k88 wrote: every function should validate its input parameters and the data it has access to before using them
I agree with that, the question is what method you use to check them. If you're passing over one or two type parameters, then a null check is okay, but for anything other than that I'd pass an object and have a separate validator for that object type.
FluentValidation is a pretty good library for abstracting validation away from your methods. Your method should really focus on what it's supposed to be doing, not extraneous tasks.
Just my two cents anyway
Ah, I see you have the machine that goes ping. This is my favorite. You see we lease it back from the company we sold it to and that way it comes under the monthly current budget and not the capital account.
modified 31-Aug-21 21:01pm.
|
|
|
|
|
Brent Jenkins wrote: Your method should really focus on what it's supposed to be doing, not extraneous tasks. Checking if it's going to plunge to a horrible and toothy death is very well part of its responsibility. Adding classes on classes on classes for a couple of operations that strongly depend on what the method is about to do on data* is a good way to create OOP spaghetti code. Been there done that got the t-shirt and I'm still maintaining that frigging mess, whose debug caused me a lot of lost hair and temper.
* I may have a parameter that should be != 0 but to the current method it does not matter, or on the other hand each other method would accept a != 0 but he needs it to be strictly > threshold. Adding a validator class and method for its conditions only is overkill. Just check them and go on. Also it help to contextualize logging and debugging wherever reflection is not an option.
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
den2k88 wrote: I may have a parameter that should be != 0 but to the current method it does not matter, or on the other hand each other method would accept a != 0 but he needs it to be strictly > threshold.
Sounds like an inconsistent architecture to me, but whatever works for you is fine
Ah, I see you have the machine that goes ping. This is my favorite. You see we lease it back from the company we sold it to and that way it comes under the monthly current budget and not the capital account.
modified 31-Aug-21 21:01pm.
|
|
|
|
|
I skipped a detail, sorry: I'm mixing private methods with public ones. For public methods a validator or similar construct is the cleanest solution. What I said before, if applied to interface methods, would be inconsistent at best!
CALL APOGEE, SAY AARDWOLF
GCS d--- s-/++ a- C++++ U+++ P- L- E-- W++ N++ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t++ 5? X R++ tv-- b+ DI+++ D++ G e++>+++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
If you think 'goto' is evil, try writing an Assembly program without JMP. -- TNCaver
"Go ahead, make my day"
|
|
|
|
|
For me it comes down to how many times I'm writing the same code.
If it's more than once, then it should probably be in a method in a class of it's own unless it's complete unavoidable because of the limitations of the language/framework. To me, that's SOP for OOP code.
Ah, I see you have the machine that goes ping. This is my favorite. You see we lease it back from the company we sold it to and that way it comes under the monthly current budget and not the capital account.
modified 31-Aug-21 21:01pm.
|
|
|
|
|