[Gambas-user] Removing / Modifying IsXXXX() functions in Gambas3

Ron ron at ...1740...
Wed Nov 24 13:10:57 CET 2010


On 24-11-2010 12:28, Benoît Minisini wrote:
>> On 24-11-2010 12:08, Benoît Minisini wrote:
>>> Hi,
>>>
>>> I'm currently thinking about modifying/removing all IsXXXX() functions in
>>> Gambas 3.
>>>
>>> They mainly test the datatype of their expression. So, either the
>>> datatype is known at compile time, and there should be no need of
>>> testing it ; either you are using a Variant, and you can use TypeOf() to
>>> get the datatype of the value.
>>>
>>> I will replace them by some functions that will test if a value can be
>>> converted safely from a string by using localization. This is what most
>>> users expected from these functions.
>>>
>>> For exemple, in french localization:
>>> 	IsDate("13/2/20") ->   True
>>> 	IsNumber("3,34") ->   True
>>> 	IsInteger("3,34") ->   False
>>> 	IsNumber("3.34") ->   False
>>>
>>> Internally, they will use Val() and see if the conversion works.
>>>
>>> I will kept most of the name, so there will be a big incompatibility
>>> between Gambas 2, current Gambas 3, and final Gambas 3.
>>>
>>> What do you think about that?
>>>
>>> Who is using the IsXXXX() functions, and in which context?
>> I use these in my project, a lot less than expected at first:
>>
>> Bluetooth.module:        IF IsInteger(Val(sRSSI)) THEN
>> Bluetooth.module:          iRSSI = IsInteger(Val(sRSSI))
>> Events.module:      IF rResult!rerunenabled = TRUE AND IF
>> IsDate(rResult!lastrun) THEN
>> Events.module:  IF IsBoolean(sValue) THEN sValue = Main.DisplayBool(sValue)
>> Events.module:  IF IsBoolean(sCond) THEN sCond = Main.DisplayBool(sCond)
>> Events.module:  ELSE IF IsBoolean(vResult) THEN
>> JSON.module:  IF NOT IsLetter(sCar) THEN RETURN sCar
>> JSON.module:    IF NOT IsLetter(sCar) THEN
>> JSON.module:  IF IsNull(vNumber) THEN Error.Raise("Incorrect number")
>> JSON.module:  ELSE IF sCar = "-" OR IF IsDigit(sCar) THEN
>> Mail.module:    IF IsString(Main.GlobalVar["Minute"]) THEN
>> Main.GlobalVar["Minute"] = Val(Main.GlobalVar["Minute"])
>> Main.module:  IF NOT IsNull(vValue) THEN
>> Main.module:    IF IsNumber(Val(tv[k, col].Text)) THEN
>> Main.module:    IF IsNumber(Val(gv[k, col].Text)) THEN
>> Main.module:PUBLIC FUNCTION IsTime(sString AS String) AS Boolean
>> Main.module:PUBLIC FUNCTION IsBool(sStr AS String) AS Boolean
>> CDenon.class:      IF IsInteger(sValue) THEN
>> CDenon.class:      IF IsInteger(sValue) THEN
>> CDenon.class:      IF IsNull(Val(sZonecat)) THEN
>> CRFXComRX.class:    IF IsDigit(Hex(RecBuf[4])) AND IF
>> IsDigit(Hex(Lsr(RecBuf[3], 4))) THEN
>> CSqueezeServer.class:    ELSE IF IsLetter(sCar) OR IF IsDigit(sCar) OR
>> IF InStr("*-._", sCar) THEN
>> FConditionEditor.class:  IF NOT
>> (Main.IsBool(Events.EvalFormula(taFormula.Text))) THEN
>> FConditionEditor.class:      IF IsBoolean(vVal) THEN
>> FDebug.class:    IF IsBoolean(vValue) THEN
>> FTriggerEditor.class:    IF IsBoolean(Main.GlobalVar[cmbVariables.Text])
>> THEN
>> FTriggerEditor.class:    ELSE IF NOT
>> IsNumber(Main.GlobalVar[cmbVariables.Text]) THEN
>> FTriggerEditor.class:    IF IsNumber(Val(txtDeviceValue.Text)) THEN
>>
>> Regards,
>> Ron_2nd.
>>
> When you do IsNumber(Val(...)), you actually want the new behaviour I want to
> implement: checking if a string can be safely converted to what you want. In
> the new syntax, you will directly do IsNumber(...).
>
> The IsDigit(), IsLetter()... functions are not concerned by the change.
>
> IsNull() will be kept unchanged.
>
> Then, please tell me what you are testing exactly with these lines:
>
> Events.module:      IF rResult!rerunenabled = TRUE AND IF
> IsDate(rResult!lastrun) THEN

It appears to be just a test if the db record field has a date value in 
it, instead of an empty value.

> Events.module:  IF IsBoolean(sValue) THEN sValue = Main.DisplayBool(sValue)
> Events.module:  IF IsBoolean(sCond) THEN sCond = Main.DisplayBool(sCond)
> Events.module:  ELSE IF IsBoolean(vResult) THEN
---
PUBLIC SUB CheckCondition(sValue AS Variant, sOperand AS String, sCond 
AS Variant, OPTIONAL bMute AS Boolean) AS Boolean

   DIM bReturn AS Boolean

   IF IsBoolean(sValue) THEN sValue = Main.DisplayBool(sValue)
   IF IsBoolean(sCond) THEN sCond = Main.DisplayBool(sCond)
---

CheckConditions(), has variants as arguments.
If the variant sValue is a Boolean, then change it to a string value 
with "True" "False" as content, so that conversion and compare tests 
(below)  after that can be more generic.

---
   SELECT sOperand
     CASE "="
       IF Comp(sValue, sCond) = 0 THEN bReturn = TRUE
     CASE "<>"
       IF sValue <> sCond THEN bReturn = TRUE
     CASE ">"
       IF CFloat(Replace(sValue, ",", ".", gb.String)) > 
CFloat(Replace(sCond, ",", ".", gb.String)) THEN bReturn = TRUE
     CASE "<"
       IF CFloat(Replace(sValue, ",", ".", gb.String)) < 
CFloat(Replace(sCond, ",", ".", gb.String)) THEN bReturn = TRUE
     CASE ELSE
       IF Main.bEventsDebug THEN Main.WriteDebugLog(("[Events] 2c. 
Unsupported operand '" & sOperand & "' found!"))
   END SELECT
   IF Main.bEventsDebug AND IF NOT bMute THEN 
Main.WriteDebugLog(("[Events] 2c. Check condition '") & sValue & " " & 
sOperand & " " & sCond & "' = " & Main.DisplayBool(bReturn))
   RETURN bReturn

CATCH
   IF Main.bEventsDebug THEN Main.WriteDebugLog(("[Events] 2c. Invalid 
comparison in CheckCondition() routine!"))
   RETURN FALSE

END
---

> Mail.module:    IF IsString(Main.GlobalVar["Minute"]) THEN
> Main.GlobalVar["Minute"] = Val(Main.GlobalVar["Minute"])
Just seems to be checks to see if the variant value from that collection 
isn't empty, to prevent errors.

> CDenon.class:      IF IsInteger(sValue) THEN
> CDenon.class:      IF IsInteger(sValue) THEN

       TRY sValue = Val(sValue)
       IF IsInteger(sValue) THEN
         sValue = sValue + 80
       ELSE
         IF UCase(sValue) = "OFF" THEN sValue = 99
       ENDIF

To see if sValue contains a decibel value -18...80 , or on/off/up/down.

> FConditionEditor.class:      IF IsBoolean(vVal) THEN

       TRY vVal = Main.GlobalVar[Right(tvVariables.Current.Key, 
Len(tvVariables.Current.Key) - 4)]
       IF IsBoolean(vVal) THEN
         sVal = Main.DisplayBool(vVal)
       ELSE
         sVal = vVal
       ENDIF

vVal can be strings, numbers or booleans, if its a boolean, change it to 
"True", "False", otherwise just a T or nothing is shown in TableView.

> FDebug.class:    IF IsBoolean(vValue) THEN
Same here.
> FTriggerEditor.class:    IF IsBoolean(Main.GlobalVar[cmbVariables.Text])
> THEN
> FTriggerEditor.class:    ELSE IF NOT
> IsNumber(Main.GlobalVar[cmbVariables.Text]) THEN
>
If value is a boolean, disable compare checkboxes <, > , on form, just 
have = and <> enabled, if it's a number allow, < and > too as operand 
for trigger rules in my event/trigger editor.

Regards,
Ron_2nd.




More information about the User mailing list