Showing posts with label ascii. Show all posts
Showing posts with label ascii. Show all posts

Monday, 24 November 2014

Syntax strings versus literal strings

There are a number of very important differences between syntax strings and literal strings, which I will attempt to highlight for you here.

Firstly, the Uniface definition of a syntax string...
Uniface enables you to determine if the data in a string value matches a desired pattern using syntax strings.  A syntax string is a group of characters and syntax codes enclosed in single quotation marks (').
So that's the first big difference right there, literal strings are in double quotes (") and syntax strings are in single quotes (')...

  literalString = "Literal string"
  syntaxString = 'Syntax string'

A syntax string is used for pattern matching, but they are much more simplistic than the regular expressions that you might be used to in other languages.  The syntax codes are quite straight forward...

  • # - one digit (0-9)
  • & - one letter (A-Z, a-z)
  • @ - one letter, digit or underscore (A-Z, a-z, 0-9, _)
  • ~& - one extended letter
  • ~@ - one extended letter, digit or underscore
  • ? - one ASCII character
  • A-Z - that letter, in uppercase
  • a-z - that letter, in uppercase or lowercase

On top of these are a few other syntax codes of note...

  • If you want to search for the literal version of a syntax code, eg. you want to search for the hash character (#) not a digit (0-9), then you can escape the syntax code using % before it.  Therefore, to search for a hash character it would be '%#' and to search for a percentage character it would be '%%'.
  • If you want to search for a unknown number of syntax code, eg. you want to search for 2 or more digits, then you can use * after it.  Therefore, to search for 2 or more digits it would be '###*' - in this case the first two hash characters represent one digit each, and the third hash character is part of the the syntax code '#*', which means zero or more (0-n) digits.
  • If you want part of the pattern to be optional (to match the pattern or blank) then you can put rounded brackets around it, using ( and ).  For example, '##(#)' would match with 2 or 3 digits (but not more than 3).
  • Any other character is treated literally as that character.  

Uniface also gives a handy function that can be used to convert a literal string into a syntax string, sensibly named $syntax...

  syntaxString = $syntax("Literal string")

This can be especially useful if you're storing the pattern in the database, or some other configuration.

Here are a few examples from the Uniface manuals...

Proc with Syntax String
Result
if ('#' = "123")
if ('#*' = "123")
FALSE
TRUE
if ('#*' = vValue)
if ('#*' = "%%vValue")
TRUE
TRUE
if ('&###' = "1234")
if ('@###' = "1234")
FALSE
TRUE
if ('?' = "A")
if ('??' = "A")
if ('??*' = "A")
if ('?' = "ABC")
if ('??*' = "ABC")
TRUE
FALSE
TRUE
FALSE
TRUE
if ('(#(-))&&&' = "ABC")
if ('(#(-))&&&' = "1ABC")
if ('(#(-))&&&' = "1-ABC")
if ('(#(-))&&&' = "12ABC")
TRUE
TRUE
TRUE
FALSE


I've had (occasionally heated!) discussions with developers before, when they have said that...

  if ( myVar = "Y" )

...and...

  if ( myVar = 'Y' )

...are interchangable.  

Yes, I can see that the pattern 'Y' only matches with the string "Y" and nothing else, but they are entirely different ideas, and should not be used interchangeably.  If you want to only match with "Y", then use the literal string "Y", because that's what you mean.  

In my experience, developers who say that these are interchangable are developers who don't understand what the differences are.

Summary: Syntax strings are very useful for pattern matching, but very different than literal strings.  Know the difference, and know when to use which.

Thursday, 8 May 2014

Boolean values in an if statement

Last week I wrote a post about casting in if statements, focusing on the difference between equality and identity.  Well that post started out in my mind as being about boolean values, but then I found I needed to cover that ground first.

Boolean is a rather interesting datatype in Uniface.  The description in the manuals goes like this....

The Boolean data type is interpreted as either TRUE or FALSE. An empty value, and the values 0, F, f, N, and n are interpreted as FALSE. All other values are interpreted as TRUE. 

The Uniface default packing code for boolean stores the value as "T" or "F", but a number of different packing codes can be used...


  • B - Optimum DBMS Boolean default
  • B1 - ASCII Boolean (0 or 1)
  • B2 - ASCII Boolean (F or T) *Uniface default
  • B3 - ASCII Boolean (N or Y)
  • B4 - Binary Boolean (0 or 1)
  • B5 - Binary Boolean (0 or -1)


This means that it is always safest to reference a boolean in an if statement without a relational operator, like this...

  variables
    boolean b
  endvariables

  if ( b )
    putmess "b is True"
  endif
  if ( !b )
    putmess "b is False"

  endif

As empty values are interpreted as false, this example would output "b is False".

This is fine, as long as you know that you've got a boolean datatype.  However, I've seen developers get into trouble when they use this type of if statement (without a relational operator) but with other datatypes.

For example, to check a blank string in javascript, you could easily do something like this...

  var s = "";
  if(!s) {
    alert "s is blank";

  }

If you translate this directly into Uniface, then you get something like this...

  variables
    string s
  endvariables

  s = ""
  if ( !s )
    putmess "s is blank"

  endif

And this works, no problem here.  Empty string is interpreted as false and you get the same result.

Consider this though; what if s is set to "0"?  

In javascript, we would not get the alert - this is because the string is not blank, so quite right!  However, in Uniface we do get the message saying that s is blank, even though it's not.  This is because "0" is interpreted as false.

Summary: In an if statement, if you've got a boolean datatype then don't use a relational operator, but if you've got any other datatype then do use one.