Critical
CASE expressions should end with ELSE clauses
Description
The "CASE expressions should end with ELSE clauses" rule states that all CASE expressions used in PowerBuilder code should be concluded with an ELSE clause, regardless of whether the ELSE clause contains any code or not. This is done to ensure that all possible cases are accounted for in the CASE expression, and that the code is robust and reliable. Without an ELSE clause, a CASE expression may not be able to handle unexpected inputs or values, which can cause the code to fail or produce unexpected results.
Key Benefits
- Easier to read: CASE expressions are easier to read than nested IF statements, as they are more concise and structured.
- More efficient: CASE expressions can be more efficient to execute than nested IF statements.
- ELSE clause: CASE expressions should end with ELSE clauses to ensure that an output is returned, regardless of the condition evaluated.
Non-compliant Code Example
private function string TestFunctionaCall (int cnt)
string sle_message
CHOOSE CASE Real(cnt)
CASE is < 10
sle_message = " is < 10"
CASE 11 to 20
sle_message = "is 11 to 20"
END CHOOSE //Non compliant code (Case statements ends without ELSE clauses)
return ""
end function
event vg_extendedaction;
integer i_colnum, i
String s_modify, s_objecttype
datawindow ldw_target
string ls_column
CHOOSE CASE as_action
CASE "disable column" // Extend 'disable column' action
// Verify if the type of the target object is correct for this action
IF TypeOf (apo_target_object) = datawindow! THEN
// This action can disable a group of columns. Each column is separated by comma.
ldw_target = apo_target_object
DO WHILE as_param <> ""
ls_column = vg_f_get_token(as_param,",")
// Make the column's background opaque
IF ldw_target.Modify (ls_column + ".Background.Mode='1'") <> "" THEN
Return -1
END IF
LOOP
Return 1
ELSE
Return -1
END IF
CASE "enable column" // Extend 'enable column' action
// Verify if the type of the target object is correct for this action
IF TypeOf (apo_target_object) = datawindow! THEN
// This action can disable a group of columns. Each column is separated by comma.
ldw_target = apo_target_object
DO WHILE as_param <> ""
ls_column = vg_f_get_token(as_param,",")
// Make the column's background transparent
IF ldw_target.Modify (ls_column + ".Background.Mode='1'") <> "" THEN
Return -1
END IF
LOOP
Return 1
ELSE
Return -1
END IF
CASE "extended readonly" // Add a specific action
if TypeOf (apo_target_object) <> datawindow! THEN Return -1
ldw_target = apo_target_object
IF ldw_target.Modify ("DataWindow.ReadOnly='Yes'") <> "" THEN
Return -1
END IF
i_colnum = Integer(ldw_target.Describe("datawindow.column.count"))
IF i_colnum < 1 THEN Return -1
FOR i = 1 TO i_colnum
IF Long(ldw_target.describe("#" + String(i) + ".x")) <> 0 THEN
s_modify = s_modify + " #"+String(i)+".background.mode = '1'"
END IF
NEXT
IF ldw_target.Modify(s_modify) <> "" THEN
Return -1
END IF
Return 1
END CHOOSE //Non compliant code(Case statements ends without ELSE clauses)
Return 2
end event
Compliant Code Example
private function string TestFunctionaCall (int cnt)
string sle_message
CHOOSE CASE Real(cnt)
CASE is < 10
sle_message = "" is < 10""
CASE 11 to 20
sle_message = ""is 11 to 20""
CASE Else //Compliant code
sle_message = ""is > 20""
END CHOOSE
return ""
end function
event vg_extendedaction;
integer i_colnum, i
String s_modify, s_objecttype
datawindow ldw_target
string ls_column
CHOOSE CASE as_action
CASE "disable column" // Extend 'disable column' action
// Verify if the type of the target object is correct for this action
IF TypeOf (apo_target_object) = datawindow! THEN
// This action can disable a group of columns. Each column is separated by comma.
ldw_target = apo_target_object
DO WHILE as_param <> ""
ls_column = vg_f_get_token(as_param,",")
// Make the column's background opaque
IF ldw_target.Modify (ls_column + ".Background.Mode='1'") <> "" THEN
Return -1
END IF
LOOP
Return 1
ELSE
Return -1
END IF
CASE "enable column" // Extend 'enable column' action
// Verify if the type of the target object is correct for this action
IF TypeOf (apo_target_object) = datawindow! THEN
// This action can disable a group of columns. Each column is separated by comma.
ldw_target = apo_target_object
DO WHILE as_param <> ""
ls_column = vg_f_get_token(as_param,",")
// Make the column's background transparent
IF ldw_target.Modify (ls_column + ".Background.Mode='1'") <> "" THEN
Return -1
END IF
LOOP
Return 1
ELSE
Return -1
END IF
CASE "extended readonly" // Add a specific action
if TypeOf (apo_target_object) <> datawindow! THEN Return -1
ldw_target = apo_target_object
IF ldw_target.Modify ("DataWindow.ReadOnly='Yes'") <> "" THEN
Return -1
END IF
i_colnum = Integer(ldw_target.Describe("datawindow.column.count"))
IF i_colnum < 1 THEN Return -1
FOR i = 1 TO i_colnum
IF Long(ldw_target.describe("#" + String(i) + ".x")) <> 0 THEN
s_modify = s_modify + " #"+String(i)+".background.mode = '1'"
END IF
NEXT
IF ldw_target.Modify(s_modify) <> "" THEN
Return -1
END IF
Return 1
CASE Else //Compliant code
Return -1
END CHOOSE
Return 2
end event