I have a function that is similar to this:
public sub TestFunction() As Boolean
On Error GoTo NewError:
Dim testObject As New TestObject
For TestVaiable 0 to 1000
TestObject.TestMethod(TestVariable)
Next
TestFunction = True
Exit function
NewError:
TestFunction = False
End Function
I have two questions:
1) Is it bad practice to keep reusing an object in a loop? I don't think it is
2)Is it bad practice to return a boolean (false) if there is an error?
It's good practice to reuse a variable in a loop.
It's good practice to reuse an object that will either be in the same state for the whole loop, or have a very simple change that relates clearly to the nature of the loop.
It's bad practice to reuse an object in such a way that it makes it harder to see what's going on with it.
It's good practice to return quickly from a Sub or Function .There's a superstition in VB about returning early that comes from other languages that are irrelevant to it, sort of a computer equivalent to people thinking you shouldn't split infinitives in English because you can't in Latin. It's nonsense.
It's bad practice to just return from a Sub or Function when you encounter an error, without any further handling unless that is the most sensible thing to do for some reason you can explain in a short comment of less than about 200 characters.
It's bad practice not to put in that comment of less than 200 characters explaining why it's okay to just return when that error happened.
Related
so i just came across some code that reads like so:
checkCalculationPeriodFrequency("7D", "7D", SHOULD_MATCH);
and
checkCalculationPeriodFrequency("7D", "8D", SHOULD_NOT_MATCH);
Let's not worry about what the code does for now (or indeed, ever), but instead, let's worry about that last parameter - the SHOULD_MATCH and SHOULD_NOT_MATCH
Its something i've thought of before but thought might be "bad" to do (inasmuch as "bad" holds any real meaning in a postmodernist world).
above, those values are declared (as you might have assumed):
private boolean SHOULD_MATCH = true;
private boolean SHOULD_NOT_MATCH = false;
I can't recall reading about "naming" the boolean parameter passed to a method call to ease readability, but it certainly makes sense (for readability, but then, it also hides what the value is, if only a teeny bit). Is this a style thing that others have found is instagram or like, soooo facebook?
Naming the argument would help with readability, especially when the alternative is usually something like
checkCalculationFrequency("7D",
"8D",
true /* should match */);
which is ugly. Having context-specific constants could be a solution to this.
I would actually go a step further and redefine the function prototype to accept an enum instead:
enum MatchType {
ShouldMatch,
ShouldNotMatch
};
void checkCalculationFrequency(string a, string b, MatchType match);
I would prefer this over a boolean, because it gives you flexibility to extend the function to accept other MatchTypes later.
I suggest you not to do this way.
First, for each object, the two members SHOULD_MATCH and SHOULD_NOT_MATCH are regenerated. And that's not good because it's not a behavior of the object. So it you want to use is, at least describe it as STATIC FINAL.
Second, I prefer to use an enum instead, because you can control completely the value of the param, i.e. when you use it, you must use either SHOULD_MATCH or SHOULD_NOT_MATCH, not just true or false. And this increase the readability too.
Regards.
It is indeed for readability. The idea is that the reader of the function call might not know immediately what the value true mean in the function call, but SHOULD_MATCH conveys the meaning immediately (and if you need to look up the actual value, you can do so with not much effort).
This becomes even more understandable if you have more than one boolean parameters in the function call: which true means what?
The next step in this logic is to create named object values (e.g. via enum) for the parameter values: you cannot pass on the wrong value to the function (e.g. in the example of three boolean parameters, nothing stops me from passing in SHOULD_MATCH for all of them, even though it does not make sense semantically for that function).
It's definitely more than a style thing.
We have a similar system that takes takes input from a switch in the form of boolean values, 1 or 0, which is pretty much the same as true or false.
In this system we declare our variables OPEN = true and CLOSED = false* and pass them into functions which perform different actions depending on the state of the switch. Now if someone happens to hook up the switch differently it may be that we now get the value 0 when it is OPEN and 1 when it is CLOSED.
By having named boolean variables we can easily adapt the system without having to change the logic throughout. The code becomes self documenting because developers can clearer see what action is meant to be taken in which case without worrying what value comes.
Of course the true purpose of the boolean value should be well documented else where and it is in our system....honest....
*(maybe we use OPEN, !OPEN I forget)
I have a VB6 function, which executes an SQL delete. The function returns a boolean depending on whether or not the deletion was successful:
Public Function Delete(ByVal RecordID As Integer) As Boolean
On Error GoTo ErrorGenerated //Execute SQL delete
Delete = True
Exit Function
ErrorGenerated: Delete = False
End Function
I read somewhere that it is better to return an integer, which dictates whether or not the deletion was successful. However, there can only be two outcomes from running the function from what I can see i.e. deleted or not deleted (not deleted if an error is thrown). Is it better to return an integer?
I'd suggest your best bet is to return an enumerated type; each value for the enumeration can then explain to the caller what the problem is in a clear and unambiguous way, and new error reasons can be added later as required without breaking anything. Something like...
Public Enum DB_ERRS
Success
NoConnection
FailedForThisReason
FailedForThatReason
FailedForOtherReason
Failed
End Enum
Then all your database access functions could return a value of this type...
Public Function Delete(ByVal RecordID As Integer) As DB_ERRS
On Error GoTo ErrorGenerated
Execute SQL delete
Delete = Success
Exit Function
ErrorGenerated:
If Err.Number = this Then
Delete = FailedForThisReason
Else
Delete = Failed
End If
End Function
Intellisense will even help you fill them in.
This is rather subjective.
One would say, return a boolean because it's as simple as it gets.
Another one would say, return an integer, because later you might want to add a third status, such as "archived," and it would break existing code.
And someone else would say, Ditch that C-style return codes. Create a sub that doesn't return anything, and raise an exception in case you need to indicate failure.
I personally prefer exceptions. But it's up to you to decide.
In terms of size, an integer is a 32-bit signed integer, while the boolean data type doesn't really have a defined size. However, it also depends on the context from where you've read about using integers over booleans.
For SOME, the difference is irrelevant when using it as a return value from functions.
However, it can be something of a preference in stored procedures if you're also considering the return value from the stored procedure. The evaluation of booleans (when converted to numbers) may lead to it being treated like a bit (0 and 1).. In any case, it's more of a subjective approach. Integers allow more flexibility, while booleans offer limitation and simplicity. Which is better? I think it's almost entirely up to you, your preference, your coding standards, your company's coding standards, or whatnot..
Just to share a link on data types :
http://msdn.microsoft.com/en-us/library/aa383751(v=vs.85).aspx
I'll throw my opinion in. I personally think that returning a boolean value is the right thing to do. Do you really care why it failed to delete? Not normally, there are only a few reasons why a delete could fail in the first place (file locked or lack of permissions). If you need to return the reason for failure so it can be handled differently in some way, then yes, return an integer. Now personally, I don't like magic numbers, so I would never return an integer and would return an enum value instead.
The return keyword is optional in ruby so for functions with only one exit point, "return result" can be safely replaced with simply "result".
Is there any Ruby-specific guidelines to when to do this?
I tend to avoid the return keyword as much as possible due to their unruly behavior in procs.
"return" in ruby is only used if you are trying to return more than one value. e.g.
return val1, val2
or if it makes sense to return earlier from a function e.g.
#check if needed param is set
return if !param
#some operations which need param
which is easier than messing your code up with cascaded if-statements.
Conclusion: Use return every time it simplifies your code or it makes it easier to understand.
I have the following VB.NET code (but for each loops are in most languages, thus the language-agnostic tag):
Public Function VerifyServiceName(ByRef sMachineName As String, ByRef sServiceName As String) As Boolean
Dim asServices As System.ServiceProcess.ServiceController() = System.ServiceProcess.ServiceController.GetServices(sMachineName)
Dim bVerified As Boolean = False
For Each sService In asServices
If sService.DisplayName = sServiceName Then bVerified = True
Next
Return bVerified
End Function
If I have X number of services to loop through, and my service name is #3. Is it better to have multiple return statements or an exit for? Or is there a more efficient way of writing this function?
I know that the time difference between looping X times and looping through 3 times could be marginal for what I am doing, but I always have performance on the brain.
I personally believe having one return at the bottom is far more readable and easier to debug than if you have return statements everywhere, as you can never tell when the function is going to exit so you end up putting breakpoints on every return statement instead of just once at the end, for example.
I think it's all down to preference though, as there are valid arguments for both ways.
Found more discussion here about the subject. I guess I am not that proficient at searching.
I would never use a goto as the target of another goto, so if there's some additional processing at the end of the function, use "break / Exit For", otherwise just return early. Otherwise you end up with lines that mean "return" but say "break"... that doesn't help maintainability.
The first thing I do in a public method is to validate every single parameter before they get any chance to get used, passed around or referenced, and then throw an exception if any of them violate the contract. I've found this to be a very good practice as it lets you catch the offender the moment the infraction is committed but then, quite often I write a very simple getter/indexer such as this:
private List<Item> m_items = ...;
public Item GetItemByIdx( int idx )
{
if( (idx < 0) || (idx >= m_items.Count) )
{
throw new ArgumentOutOfRangeException( "idx", "Invalid index" );
}
return m_items[ idx ];
}
In this case the index parameter directly relates to the indexes in the list, and I know for a fact (e.g. documentation) that the list itself will do exactly the same and will throw the same exception. Should I remove this verification or I better leave it alone?
I wanted to know what you guys think, as I'm now in the middle of refactoring a big project and I've found many cases like the above.
Thanks in advance.
It's not just a matter of taste, consider
if (!File.Exists(fileName)) throw new ArgumentException("...");
var s = File.OpenText(fileName);
This looks similar to your example but there are several reasons (concurrency, access rights) why the OpenText() method could still fail, even with a FileNotFound error. So the Exists-check is just giving a false feeling of security and control.
It is a mind-set thing, when you are writing the GetItemByIdx method it probably looks quite sensible. But if you look around in a random piece of code there are usually lots of assumptions you could check before proceeding. It's just not practical to check them all, over and over. We have to be selective.
So in a simple pass-along method like GetItemByIdx I would argue against redundant checks. But as soon as the function adds more functionality or if there is a very explicit specification that says something about idx that argument turns around.
As a rule of thumb an exception should be thrown when a well defined condition is broken and that condition is relevant at the current level. If the condition belongs to a lower level, then let that level handle it.
I would only do parameter verification where it would lead to some improvement in code behavior. Since you know, in this case, that the check will be performed by the List itself, then your own check is redundant and provides no extra value, so I wouldn't bother.
It's true that possibly you duplicated work that's already been done in the API, but it's there now. If your error handling framework works and is solid, and isn't causing performance issues (profiling IYF) then I reckon leave it, and gradually phase it out if you have time. It doesn't sound like a top priority!