I have seen a few examples lately where if statements are written as follows:
if ( false === $testValue) {
//do something
}
as opposed to the more general:
if ($testValue === false) {
//do something
}
Clearly it is a style issue and it has no bearing on the result, but my question is can anyone say why anyone would use this style and where it comes from.
The code examples I have seen with this style have been from seriously good programmers so I dont think its a necessarily a bad style.
It's so that if you accidentally type = (assignment) instead of == (comparison), the compiler complains that the constant cannot be assigned to.
Compare:
if (false = $testValue) {
// does not compile, cannot assign to constant
}
to:
if ($testValue = false) {
// assigns false to $testValue, never evaluates to true
}
The former doesn't compile, the latter does and has a bug.
I used to see checks like this in C and C++:
if (null == x)
The reason for it was that mistyping = for == would make no sense to the compiler, because assignment to null or a constant would be an error.
In something like C++ (I'm not sure what language you're using there with the ===) if you have
if(x == 2), and you write it if(x=2) (so the value is assigned an not checked for equality) this doesn't cause a compiler error (most compilers today will warn you about it), but if you write if (2=x) instead of if(2==x) that will defintely produce an error.
It's to prevent assignment when comparison was intended.
I don't like this style myself but I see it a lot from our Indian developers so maybe it's being taught over there.
It's completely unnecessary if a '0 warnings, 0 errors' build policy was adhered to, and anyone who uses this style is not likely to provide clean building code.
Related
Please note that this question ONLY relates to the popular SQLite.swift library, stephencelis/SQLite.swift
With SQLite.swift you can
let a = Expression<String>("a")
let b = Expression<String>("b")
and so on. But how do you
select a.x, a.y, ifnull(b.q, 'default text'), a.z
from a
left join b on blah
how do you make an expression for an inline sql ifnull clause?
(The doco mentions that Expression has an init(literal:) initializer - maybe it's relevant - but it's undocumented and has unusual binding arguments.)
Please note, I'm completely aware that you could make the value optional
let q = Expression<String?>("q")
and then just put in the default later;
I am asking how to express "ifnull(b.q, 'default text')" as an Expression (or, learn it is impossible) so that value will actually be used in the SQL expression.
Once again, this question relates only to the library /stephencelis/SQLite.swift
I dislike answering my own question,
but honestly the realistic answer here is:
nowadays you have to use GRDB like everyone else, github.com/groue/GRDB.swift
The older SQL-wrapper libraries (as magnificent, awesome, incredible as they were at the time) are honestly just
totally out of date now, technology-wise
not honestly maintained realistically any more
As of late 2017 GRDB is the only real possibility.
Maybe this is too late, but anyway. I've checked the source code, there is function
public func ??<V : Value>(optional: Expression<V?>, defaultValue: V) -> Expression<V> {
return "ifnull".wrap([optional, defaultValue])
}
So you have to make the value optional
row.get(Expression<Double?>("q")) ?? 0 //this will be equals ifnull(q, 0)
While the Swift compiler (Xcode 7.2) seems perfectly correct in diagnosing an error for some source text equivalent to the following, it took long to detect the actual error made. Reason: the programmer needs to look not at the text marked, but elsewhere, thus mislead, wondering why an optional string and a non-optional string can not be operands of ??...
struct Outer {
var text : String
}
var opt : String?
var context : Outer
context = opt ?? "abc"
Obviously, the last line should have had context.text as the variable to be assigned. This is diagnosed:
confusion2.swift:9:19: error: binary operator '??' cannot be applied\
to operands of type 'String?' and 'String'
context = opt ?? "abc"
~~~ ^ ~~~~~
The message is formally correct. (I am assuming that type checking the left hand side establishes an expected type (Outer) for the right hand side, and this, then, renders the expression as not working, type-wise.) Taken literally, though, the diagnosis is wrong, as is seen when fixing the left hand side: ?? can be applied to operands of type String? and String.
Now, if this is as good as it gets, currently, in terms of compiler messages, what are good coping strategies? Is remembering
Type inference!
Context!
…
a start? Is there a more systematical approach? A check list?
Update (I'm adding to the list as answers come in. Thanks!)
break statements apart, so as to have several lines checked separately (#vacawama)
Beware of optionals (such as values got from dictionaries), see testSwitchOpt below
Another one
enum T {
case Str(String)
case Integer(Int)
}
func testSwitchOpt(x : T?) -> Int {
switch x {
case .Integer(let r): return r
default: return 0
}
}
The compiler says
optandswitch.swift:8:15: error: enum case 'Integer' not found in type 'T?'
case .Integer(let r): return r
A fix is to write switch x! (or a more cautious let), so as to make type checking address the proper type, I guess.
I could, perhaps should, file some report at Apple, but the issue seems to represent a recurring subject—I have seen this with other compilers—and I was hoping for some general and re-usable hints, if you don't mind sharing them.
Swift's type inference system is great in general, but it can lead to very confusing to outright wrong error messages.
When you get one of these Swift error messages that makes no sense, a good strategy is to break the line into parts. This will allow Swift to return a better error message before it goes too far down the wrong path.
For example, in your case, if you introduce a temporary variable, the real problem becomes clear:
// context = opt ?? "abc"
let temp = opt ?? "abc"
context = temp
Now the error message reads:
Cannot assign value of type 'String' to type 'Outer'
I want to know what could be the shortest linq query instead of following if statement.
public enum ErrorMessage { Error1=1, Error2=2, Error3=3, Error4=4 }
ErrorMessage error = ErrorMessage.Error4;
if (error == ErrorMessage.Error1 || error == ErrorMessage.Error2)
{
//do something
}
Linq will make this code complicated,
code you provide is readable, fast and maintainable more than Linq will be
You could use
if (new [] {ErrorMessage.Error1, ErrorMessage.Error2}.Contains(error))
{
//do something
}
or
var bad_errors = new [] {ErrorMessage.Error1, ErrorMessage.Error2};
if (bad_errors.Contains(error))
{
//do something
}
if a single call to an extension method is LINQ enough for you.
I guess to most C# developers such a pattern seems strange (and it totally is), but if you're already working on a dynamically created list of errors you want to check against...
Otherwise, stick with if.
It actually works nicer in languages with less boilerplate, e.g. Python, where this pattern is commonly used and looks a lot nicer:
if error in (Error1, Error2):
# do something
How much information hiding is necessary? I have boilerplate code before I delete a record, it looks like this:
public override void OrderProcessing_Delete(Dictionary<string, object> pkColumns)
{
var c = Connect();
using (var cmd = new NpgsqlCommand("SELECT COUNT(*) FROM orders WHERE order_id = :_order_id", c)
{ Parameters = { {"_order_id", pkColumns["order_id"]} } } )
{
var count = (long)cmd.ExecuteScalar();
// deletion's boilerplate code...
if (count == 0) throw new RecordNotFoundException();
else if (count > 1) throw new DatabaseStructureChangedException();
// ...boiler plate code
}
// deleting of table(s) goes here...
}
NOTE: boilerplate code is code-generated, including the "using (var cmd = new NpgsqlCommand( ... )"
But I'm seriously thinking to refactor the boiler plate code, I wanted a more succint code. This is how I envision to refactor the code (made nicer with extension method (not the sole reason ;))
using (var cmd = new NpgsqlCommand("SELECT COUNT(*) FROM orders WHERE order_id = :_order_id", c)
{ Parameters = { {"_order_id", pkColumns["order_id"]} } } )
{
cmd.VerifyDeletion(); // [EDIT: was ExecuteWithVerification before]
}
I wanted the executescalar and the boilerplate code to goes inside the extension method.
For my code above, does it warrants code refactoring / information hiding? Is my refactored operation looks too opaque?
I would say that your refactor is extremely good, if your new single line of code replaces a handful of lines of code in many places in your program. Especially since the functionality is going to be the same in all of those places.
The programmer coming after you and looking at your code will simply look at the definition of the extension method to find out what it does, and now he knows that this code is defined in one place, so there is no possibility of it differing from place to place.
Try it if you must, but my feeling is it's not about succinctness but whether or not you want to enforce the behavior every time or most of the time. And by extension, if the verify-condition changes that it would likely change across the board.
Basically, reducing a small chunk of boiler-plate code doesn't necessarily make things more succinct; it's just one more bit of abstractness the developer has to wade through and understand.
As a developer, I'd have no idea what "ExecuteWithVerify" means. What exactly are we verifying? I'd have to look it up and remember it. But with the boiler-plate code, I can look at the code and understand exactly what's going on.
And by NOT reducing it to a separate method I can also tune the boiler-plate code for cases where exceptions need to be thrown for differing conditions.
It's not information-hiding when you extract or refactor your code. It's only information-hiding when you start restricting access to your extension definition after refactoring.
"new" operator within a Class (except for the Constructor) should be Avoided at all costs. This is what you need to refactor here.
I've been doing a massive code review and one pattern I notice all over the place is this:
public bool MethodName()
{
bool returnValue = false;
if (expression)
{
// do something
returnValue = MethodCall();
}
else
{
// do something else
returnValue = Expression;
}
return returnValue;
}
This is not how I would have done this I would have just returned the value when I knew what it was. which of these two patterns is more correct?
I stress that the logic always seems to be structured such that the return value is assigned in one plave only and no code is executed after it's assigned.
A lot of people recommend having only one exit point from your methods. The pattern you describe above follows that recommendation.
The main gist of that recommendation is that if ou have to cleanup some memory or state before returning from the method, it's better to have that code in one place only. having multiple exit points leads to either duplication of cleanup code or potential problems due to missing cleanup code at one or more of the exit points.
Of course, if your method is couple of lines long, or doesn't need any cleanup, you could have multiple returns.
I would have used ternary, to reduce control structures...
return expression ? MethodCall() : Expression;
I suspect I will be in the minority but I like the style presented in the example. It is easy to add a log statement and set a breakpoint, IMO. Plus, when used in a consistent way, it seems easier to "pattern match" than having multiple returns.
I'm not sure there is a "correct" answer on this, however.
Some learning institutes and books advocate the single return practice.
Whether it's better or not is subjective.
That looks like a part of a bad OOP design. Perhaps it should be refactored on the higher level than inside of a single method.
Otherwise, I prefer using a ternary operator, like this:
return expression ? MethodCall() : Expression;
It is shorter and more readable.
Return from a method right away in any of these situations:
You've found a boundary condition and need to return a unique or sentinel value: if (node.next = null) return NO_VALUE_FOUND;
A required value/state is false, so the rest of the method does not apply (aka a guard clause). E.g.: if (listeners == null) return null;
The method's purpose is to find and return a specific value, e.g.: if (nodes[i].value == searchValue) return i;
You're in a clause which returns a unique value from the method not used elsewhere in the method: if (userNameFromDb.equals(SUPER_USER)) return getSuperUserAccount();
Otherwise, it is useful to have only one return statement so that it's easier to add debug logging, resource cleanup and follow the logic. I try to handle all the above 4 cases first, if they apply, then declare a variable named result(s) as late as possible and assign values to that as needed.
They both accomplish the same task. Some say that a method should only have one entry and one exit point.
I use this, too. The idea is that resources can be freed in the normal flow of the program. If you jump out of a method at 20 different places, and you need to call cleanUp() before, you'll have to add yet another cleanup method 20 times (or refactor everything)
I guess that the coder has taken the design of defining an object toReturn at the top of the method (e.g., List<Foo> toReturn = new ArrayList<Foo>();) and then populating it during the method call, and somehow decided to apply it to a boolean return type, which is odd.
Could also be a side effect of a coding standard that states that you can't return in the middle of a method body, only at the end.
Even if no code is executed after the return value is assigned now it does not mean that some code will not have to be added later.
It's not the smallest piece of code which could be used but it is very refactoring-friendly.
Delphi forces this pattern by automatically creating a variable called "Result" which will be of the function's return type. Whatever "Result" is when the function exits, is your return value. So there's no "return" keyword at all.
function MethodName : boolean;
begin
Result := False;
if Expression then begin
//do something
Result := MethodCall;
end
else begin
//do something else
Result := Expression;
end;
//possibly more code
end;
The pattern used is verbose - but it's also easier to debug if you want to know the return value without opening the Registers window and checking EAX.