Complex IF THEN statements in VB6 [duplicate] - vb6

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Does VB6 short-circuit complex conditions?
I am curious about how IF statements are executed in VB6.
For example if I have the statement
If x And y Then
'execute some code
End If
Does the code move on if x is not true? Or does it go ahead and evaluate y even though there is no logical point?
Another example
If x Or y Then
'execute some code
End If
Does the code continue and evaluate y if x is true?
EDIT:
Is there a way to avoid nested IF statements if I want to evaluate very complex conditions and I don't want to waste CPU time?

What you are describing is short circuiting logic, and VB6 doesn't have it...
For example, in VB.Net you might write
If x AndAlso y then...
In this case y is not tested if x turns out to be false.
In your VB6 example, you'll get a Object or With block variable not set error if you try something such as:
Dim x as Object
If Not x Is Nothing And x.y=1 Then
Since object x has not been instantiated.

An unwieldy or-like statement that exhibits short circuiting behaviour:
select case True
case a(), b(), c()
'//if a returns true b & c are not invoked, if b returns true a & b were invoked
case else
...

To answer your edit - avoiding nested IF statements, you can use Select Case, covered in the latter half of this article.
Code snippet from the article:
Select Case strShiftCode
Case "1"
sngShiftRate = sngHourlyRate
Case "2"
sngShiftRate = sngHourlyRate * 1.1
Case "3"
sngShiftRate = sngHourlyRate * 1.5
Case Else
Print "Shift Code Error"
End Select

Related

Vb6 Case a to b in Select Case(Switch) Enum

I saw this kind of code in vb6.
Private Enum enmMain
STEP_INIT = 1
STEP_RUN = 2
STEP_SLEEP = 3
STEP_SUSPEND = 4
STEP_ERROR = 5
End Enum
Private mStep As enmMain
Select Case mStep
Case Is <= enmMain.STEP_RUN
'Do something
Case enmMain.STEP_RUN To enmMain.STEP_ERROR
'Do something
I don't understand this:
Case enmMain.STEP_RUN To enmMain.STEP_ERROR
If it goes into that case when it meets this condition:
the latest value is STEP_RUN
current value is STEP_ERROR
How does it work?
I am posting on mobile can't write clean.
It means that the case statement will be satisfied by all values of mStep that are between 2 and 5, inclusive.
So there is an imprecision in code. Because the value STEP_RUN appears in an inclusive test twice (see the <= operator). Which behaviour is intended for STEP_RUN, the first or the second? You need to figure it out by understanding the program's logic.
Well, let's read the manual:
If testexpression matches any Case expressionlist expression, the statements following that Case clause are executed up to the next Case clause, or, for the last clause, up to End Select. Control then passes to the statement following End Select. If testexpression matches an expressionlist expression in more than one Case clause, only the statements following the first match are executed.
Select Case will run the first block that matches, and the criteria you can use to match are much more flexible than those allowed in many other languages. Case Is <= enmMain.STEP_RUN Will run for any value of mStep that is less than or equal to 2, and Case enmMain.STEP_RUN To enmMain.STEP_ERROR would run for any value between 2 and 5 inclusive.
Now it seems like somebody didn't quite understand what that meant, though, or at least wrote it in a confusing way, because for a value of 2 only the first Case would run, since as the section I quoted says only the first match is executed.
So the end result is that first 'Do something will run on values of 2 or less, and the second 'Do something will run on values of 3, 4, or 5.

Compound Boolean Expr: Void Value Expression

def success?
return #fhosts.empty? and #khosts.empty? and #shosts.any?
end
When I run that instance method, I get an error:
/home/fandingo/code/management/lib/ht.rb:37: void value expression
return #fhosts.empty? and #khosts.empty? and #shosts.any?
I'm confused by what's happening since this works
def success?
#fhosts.empty? and #khosts.empty? and #shosts.any?
# This also works
# r = #fhosts.empty? and #khosts.empty? and #shosts.any?
# return r
end
I'm coming from a Python background, and I don't want anything to do with implicit returns. Programming has plenty of landmines as it is.
If we have an arbitrary expression, E, that consists of boolean operations and and or together, here are some operations we could perform:
if E -- works
E -- works
* v = E -- works
return E -- broken
Why doesn't the last case work?
Edit: Actually v = E doesn't work. Only
v = Ei
is evaluated. Ei+1...k are ignored.
This is likely due to the very weak binding of and which causes it to parse out differently than you expect:
return x and y
This actually means:
(return x) and y
Since you're returning immediately it doesn't have a chance to evaluate the remainder of the expression.
Your version without return is correct:
x and y
This doesn't have a binding issue and is more idiomatic Ruby. Remember you only need to put an explicit return if you're trying to force an exit before the last line of the method. Being opposed to implicit returns is going to make your code look heavily non-Ruby. They're one of the reasons Ruby is so clean and simple, and how things like a.map { |v| v * 2 } works.
The When in Rome principle applies here. If you want to write Python-style Ruby you're going to be going against the grain. It's like saying "I don't like how you say X in your spoken language, so I'll just ignore that and do it my way."
This should also work:
return x && y
The && method is very strongly bound so return is the last thing evaluated here.
Or if you really want to use and for whatever reason:
return (x and y)

When and If in Modelica

Hi I have some puzzles about event and when in Modelica. Below is my code:
model test
Integer bar(start=5, fixed=true);
equation
when (time < 2) then
bar = 1;
end when;
annotation(experiment(StopTime=3));
end test;
My question is why I got 5 instead of 1 when time is less than 2? How can I understand the event(time < 2) in this case? What is the difference of when clause in Modelica and other programming language, like c.
The when equation is only active when the condition becomes true. In your case the condition time < 2 is true from the beginning and only becomes false.
The when-block can be intentionally translated to
b = time < 2;
if not(pre(b)) and b then
bar = 1;
else
bar = pre(bar);
end
For further information you can consult the specification https://modelica.org/documents/ModelicaSpec33Revision1.pdf.
Tobias' answer is correct. But I think for beginners it might be a little daunting to invoke the pre construct or send them to the specification. So in addition to Tobias' answer, I would point the interested reader to this question as well as this chapter in my book. Of specific interest (I suspect) would be this subsection on when and how it is different from if.

Do "Ors" Evaluate The Whole Expression?

Say I have the following statement logic (I'll be using VBA for this example, but it also pertains to other languages)
x = 1
y = 2
z = 1000
If x = 1 Or y = 2 Or z = 4 Then
Execute Code
End
Does the compiler or executing program find that the first value is true, and then continue to Execute Code or does it finish off the rest of the statement?
I can't speak for VBA, but I can say that it is language specific. In some languages, the programmer has the ability to use "short-circuit" AND and OR expressions. Short-circuiting is the process of no longer evaluating a boolean expression if the result has already been determined.
If using a short-circuited AND, the boolean operation stops early if a FALSE is found. If using a short-circuited OR, the boolean operation stops early if a TRUE is found.
For example, in Java:
a || b is a short-circuited OR
a | b is a non-short-circuited OR
a && b is a short-circuited AND
a & b is a non-short-circuited AND
Some may ask, "why would I ever use a non-short-circuited AND or OR?" The reason for this comes when you are calling a function that returns a boolean that you want to run in every case. For example a() | b() would run both function a and function b. a() || b() only runs function b if a returns false.
I think that also in vba you can use OrElse.
'Or' (bitwise comparison) always finishes the rest of the statement, 'OrElse' (logical comparison) stops when the requirement is met.
In C++, C# and Java you can use '|' and '||'.
For example if object is null Or object.value = "" will result in a null exception when the object is empty because of the attempt to access a field from an empty object.
With OrElse the evaluation if object is null OrElse object.value = "" will stop at the first comparison when an empty object is evaluated.

Refactoring conditional variable assignment

I'm working on a project. Currently I have a fairly large conditional statement, that assigns a value to a variable based on some input parameters. So, I have something like this.
if some condition
x = some value
elsif another condition
x = a different value
...
What's the best way to refactor this? I'm hoping that I might end up with something like
x = some value if some condition || another value if another condition
Is there a pattern for this sort of thing?
Just put the assignment outside the if.
x = if some condition
some value
elsif another condition
a different value
Or you could use a Hash.
x = dict[some condition]
It's not a pattern, but an operator. The one you're referring to is the ternary operator:
If Condition is true ? Then value X : Otherwise value Y
Here is an example:
speed = 90
speed > 55 ? puts("I can't drive 55!") : puts("I'm a careful driver")
Using the ternary statement is short, sweet, and does the job.
x = some condition ? some value :
another condition ? a different value : ...
A conditional statement is also an expression, so one of the first things you can do, if the variable is the same in each condition, is:
x = if cond1
expr1
elsif cond2
expr2
....
end
If the conditions are all states of a single expression, you can make this even neater, using a case statement.
However, the next most obvious re-factoring exercise is to get the big conditional isolated into a method, which should be fed the bare minimum data required to evaluate all the conditions and expressions.
E.g.
# Where conditional is currently, and x assigned, assuming the conditionals
# need a couple of variables . . .
x = foo param1, param2
# Elsewhere
private
def foo p1, p2
if cond1
expr1
elsif cond2
expr2
....
end
end
If you want to refactor for code clarity and flexibility, consider the replacing conditional with polymorphism refactor.
There's not enough detail in your question to go much further with recommendations, but this refactor will make your code base much more resistant to change. If you receive a new requirement, it's bad form to break open the conditional and modify it (more prone to introducing bugs, more difficult to do); it's preferable to create a new object that you can plug into the existing codebase. This flexibility what the Open/Closed Principle (the "O" in the SOLID acronym) describes.

Resources