What's the meaning of "WHEN ? THEN"? - openedge

While reading some source code, I just stumbled upon the following piece of code in Progress:
WHEN ? THEN
...
In other languages, I've seen code like IF TRUE THEN ... (this code is always to be run) or IF FALSE THEN ... (this code is never to be run).
As ? means "nothing" in Progress, does this piece of code mean the same as IF FALSE THEN ...?

If that's used in a CASE statement, it compares the value used in the CASE block to the unknown value. That's similar to a switch statement in C-like languages.
CASE lOk:
WHEN TRUE THEN ...
WHEN FALSE THEN ...
WHEN ? THEN ...
END CASE .

In the expression
WHEN value[ OR WHEN value] . . . THEN
Each value is an expression that evaluates to a possible value for expression. If value matches the current value of expression, then the associated block or statement executes. The question now is, how to evaluate to an unknown or null value. This is done with the "?" character. For example:
IF myVariable = ? THEN DISPLAY "This value is unknown".
If instead you need to evaluate a comparison to an actual question mark character, all you need to do is enclose the question mark in single or double quotes.
IF myVariable = '?' THEN DISPLAY "This is a question mark".
IF myVariable = "?" THEN DISPLAY "This is a question mark".
For future reference, Progress Knowledgebase is a good place to get information.

Related

I need help figuring out why my regex does not match with what I am looking for

I am working on a R script aiming to check if a data.frame is correctly made and contains the right information at the right place.
I need to make sure a row contains the right information, so I want to use a regular expression to compare with each case of said row.
I thought maybe it did not work because I compared the regex to the value by calling the value directly from the table, but it did not work.
I used regex101.com to make sure my regular expression was correct, and it matched when the test string was put between quotes.
Then I added as.character() to the value, but it came out FALSE.
To sum up, the regex works on regex101.com, but never did on my R script
test = c("b40", "b40")
".[ab][0-8]{2}." == test[1]
FALSE
I expect the output to be TRUE, but it is always FALSE
The == is for fixed full string match and not used for substring match. For that, we can use grep
grepl("^[ab][0-8]{2}", test[1])
#[1] TRUE
Here, we match either 'a' or 'b' at the start (^) of the string followed by two digits ranging from 0 to 8 (if it should be at the end - use $)

How to find self closing tag using XQuery

I need to find Self closing tag XML in using XQuery,
for example I have two kind of XML are available.
**Example 1** : fn:matches(<root><a>Eng</a><b>maths</b></root>//b ,<b/>);
answer : true
**Example 2** : fn:matches(<root><a>Eng</a><b/></root>//b ,<b/>);
answer : true
The above example both are getting results are true
but my expectation is first one XML have no self-closing tag so it's getting false so it can any possible ? please help.
I think you misunderstood the usage of fn:matches. You can find the official specification here: https://www.w3.org/TR/xquery-operators/#func-matches. But in short, it is a means to match a string (first argument) against a regular expression (second argument).
You are providing element nodes. These get cast to strings first, so you are effectively running:
fn:matches("maths", "")
Which indeed returns true. You might be better off using fn:deep-equal.
Then again, that will not help distinguish <b></b> versus <b/> since those are considered identical in XML processors. If you are simply looking for empty elements, you can do:
let $xml := <root><a>Eng</a><b>maths</b></root>
return $xml//b[not(. = '')]
or:
let $xml := <root><a>Eng</a><b>maths</b></root>
return $xml//b[empty(node())]
HTH!

Xquery version of "NOT IN" clause not working as expected

I have an xml file which can be downloaded in the following link:
http://expirebox.com/download/483d465091802df68da10feddc1ec98c.html
I am trying to select all those movies without the styles of "live action" and "camp" in my movies.xml. To achieve this I am using the following query
for $movie in db:open("movies","movies.xml")/movies/movie
where $movie/styles/style!=("noir","anthology")
return $movie
However, all nodes in movies are getting selected. What is going wrong in my query?
Some experts are pointing out the inability of the standard not equal operator not working in this case due to the semantics of XQuery involved. However, my intention is to find a corresponding query of an SQL feature and not just understand the semantics.
!= uses set comparison logic.
For values that are not in that sequence, such as "foo", the expression "foo" != ("noir", "anthology") returns true However, the expression "noir" != ("noir", "anthology") would also return true. This is because "noir" does not equal one of the items in the sequence, "anthology", even though it also equals one of the items in the sequence as well. The expression "noir" = ("noir", "anthology") returns true because "noir" is equal to one of the items in the sequence, "noir".
Refer to the specification:
https://www.w3.org/TR/1999/REC-xpath-19991116/#booleans
NOTE: If $x is bound to a node-set, then $x="foo" does not mean the same as not($x!="foo"): the former is true if and only if some node in $x has the string-value foo; the latter is true if and only if all nodes in $x have the string-value foo.
Use:
where not($movie/styles/style=("noir","anthology"))
or:
where $movie/styles/style[not(.=("noir","anthology"))]

Case insensitive token matching

Is it possible to set the grammar to match case insensitively.
so for example a rule:
checkName = 'CHECK' Word;
would match check name as well as CHECK name
Creator of PEGKit here.
The only way to do this currently is to use a Semantic Predicate in a round-about sort of way:
checkName = { MATCHES_IGNORE_CASE(LS(1), #"check") }? Word Word;
Some explanations:
Semantic Predicates are a feature lifted directly from ANTLR. The Semantic Predicate part is the { ... }?. These can be placed anywhere in your grammar rules. They should contain either a single expression or a series of statements ending in a return statement which evaluates to a boolean value. This one contains a single expression. If the expression evaluates to false, matching of the current rule (checkName in this case) will fail. A true value will allow matching to proceed.
MATCHES_IGNORE_CASE(str, regexPattern) is a convenience macro I've defined for your use in Predicates and Actions to do regex matches. It has a case-sensitive friend: MATCHES(str, regexPattern). The second argument is an NSString* regex pattern. Meaning should be obvious.
LS(num) is another convenience macro for your use in Predicates/Actions. It means fetch a Lookahead String and the argument specifies how far to lookahead. So LS(1) means lookahead by 1. In other words, "fetch the string value of the first upcoming token the parser is about to try to match".
Notice that I'm still matching Word twice at the end there. The first Word is necessary for matching 'check' (even though it was already tested in the predicate, it was not matched and consumed). The second Word is for your name or whatever.
Hope that helps.

RegularExpressionValidator always fails, but ValidationExpression works in testing

I found the answer to this, but it's a bit of a gotcha so I wanted to share it here.
I have a regular expression that validates passwords. They should be 7 to 60 characters with at least one numeric and one alpha character. Pretty standard. I used positive lookaheads (the (?= operator) to implement it:
(?=^.{7,60}$)(?=.*[0-9].*)(?=.*[a-zA-Z].*)
I checked this expression in my unit tests using Regex.IsMatch(), and it worked fine. However, when I use it in a RegularExpressionValidator, it always fails. Why?
It's strange that I've never run into this before, but it turns out that the RegularExpressionValidator doesn't use Regex.IsMatch or JavaScript's Regex.test() -- it checks for a capturing match that exactly equals the full tested value. Here's the relevant JS code:
var rx = new RegExp(val.validationexpression);
var matches = rx.exec(value);
return (matches != null && value == matches[0]);
So if the expression is all lookaheads (which match positions, not the actual text), it will fail. This is clearer with the example of an expression that only partially matches, e.g. with \d{5}, the value "123456" would fail. It's not just that it adds "^$" around your expression and does an IsMatch. Your expression actually has to capture.
The fix in my case is this expression:
(?=^.{7,60}$)(?=.*[0-9].*).*[a-zA-Z].*
Have you tried
(?=^.{7,60}$)(?=.*[0-9].*)(?=.*[a-zA-Z].*).+
// ^^
? The regex should need something to consume.

Resources