Is there any difference in how these two conditional statements will be evaluated?
<cfif Catalog_Id eq 123 or Catalog_Id eq 456 and CatalogType eq 1></cfif>
<cfif (Catalog_Id eq 123 or Catalog_Id eq 456) and CatalogType eq 1></cfif>
From what I recall, the conditional statement will be evaluated from left to right. That means that the OR statement will be evaluated and then the AND condition will be evaluated.
In this case are the parentheses necessary or are they just for readability? Will the be evaluated in all languages in the same order?
UPDATE
For some reason, I couldn't wrap my tired brain around the concept of how this was executing. As soon as someone pointed out the obvious, I woke up and wondered how I hadn't been able to figure out the answer myself. Ugh.
The first statement is evaluated as Catalog_Id eq 123 OR (Catalog_Id eq 456 and CatalogType eq 1)
The second statement is evaluated as (Catalog_Id eq 123 or Catalog_Id eq 456) AND CatalogType eq 1
These are two every different statements. Check out Adobe's Operator precedence and evaluation ordering
Related
Let's say I have a string, maybe "Enable && Signal" for simplicity's sake.
I'd like to convert this string to standard && operations in tcl, such that Enable && Signal would return 0 if any of the value is false and 1 only when both are true.
Is there an easy way to do this, As for my case i would need a generic method where the number of arguments can be any and perform logical/relational operations like && || == <= > != etc
Any help and insights would be very much appreciated.
Thanks
I initially tried to split the arguments into conditions list and data list but could not handled the precedence of operations. Like == need to be done first and later && operations for n^n combinations
I'm assuming that in your example, Enable and Signal are Tcl variables. So, all that would be needed to be able to pass the string to expr is to prepend a '$' to all identifiers. That can be done with regsub as follows:
set str "Enable && Signal"
regsub -all {\m[A-Za-z]\w*\M} $str {$&} expr
set result [expr $expr]
Due to the \m\M, This will properly leave numbers like 1e3 alone. But this method falls short if you also want to be able to use functions, like sin(x). If that is also a requirement, a negative lookahead may help:
set str "sin(x) * cos(y)"
regsub -all {\m[A-Za-z]\w*\M(?!\()} $str {$&} expr
puts $expr
This produces: sin($x) * cos($y)
How can I detect if a string value only consists of one or more commas and nothing else. The correct value should be something like: ABC,BVC,BNM but sometimes I get value like: , or ,,, or ,, and this is not allowed. How can I detect that a string only have one or more commas and then I can create a warning to the user and stop the process.
Thank you
You can use listToArray() and arrayToList() to remove the empty items from the list and can then compare the sanitized version with the original like this:
<cfset originalInput = trim( ",,," )>
<cfset sanitizedInput = arrayToList( listToArray( originalInput, ",", false ), "," )>
<!--- Compare both --->
<cfif originalInput NEQ sanitizedInput>
<!--- Throw error --->
</cfif>
Depends on how much your input may vary, but as you currently describe it:
Something as simple as <cfif MyVar contains ",,"> would work.
If one comma (and nothing else) is a possibility, then
<cfif MyVar contains ",," OR Len(MyVar) lt 2>
Assuming any non-commas are either letters or numbers, you can do use a regular expression:
patternAlphaNumeric = "[0-9a-zA-Z]";
testString = ",,,";
if (reFind(",", testString) > 0 && refind(patternAlphaNumeric, testString) == 0)
code for all commas
else
code for other characters
If you are only concerned about detecting commas (or one or more of any character), just use ListLen().
It's a native ColdFusion function.
It ignores empty list items by default.
Its default delimiter is a comma.
So, if your_string consists only of one or more commas, then ListLen( your_string ) will always return 0.
Heads up, it also returns 0 for an empty string, so if you don't want your code to pop for empty strings, be sure to account for that.
<cfset local.myString = "string-goes-here">
<cfset local.myNewString = ReReplace(trim(local.myString),",","","ALL")>
<cfif not len(local.myNewString)>
<!--- warning to the user and stop the process --->
</cfif>
I have to include a perl script into a web system for my work, however the original author is no longer here and no one else in the office knows perl.
I've only first dealt with perl this morning and i'm stuck trying to figure out a couple lines that maybe someone might be able to help with
1] $customer = $q->param('account') || '';
2] $customer =~ s/[^\d]//g;
3] $customer ||= '';
4] if( $customer and ( $customer =~ /^10\d{5}$/ or $customer eq '1' ) ) {
5] $no_error = 1;
6] }
I found out that line 2 removes all non-numeric values, but I am not so sure how that statement actually functions..?
Again, i'm unsure to what =~ /^10\d{5}$/ means.
Line 3 is the main one i cannot figure out, i'm used to || meaning logical OR.
1) Accept the parameter if it's a value that Perl considers "true", otherwise, an empty string.
2) A regex substitution, eliminating any non-digits found in $customer.
3) If $customer is a "false" Perl value, set it to an empty string.
4) If $customer is a 'true' value, and either a 7-digit number starting with 10, or the string, '1'...
5) Set $no_error to the numeric value 1.
6) Close a block.
The || and ||= operators are explained in perldoc perlop. In some cases, they're a lurking bug because "0" may be a legitimate value for the parameter, yet would trigger the 'or' clause, which is one reason why the // and //= operators were introduced in Perl 5.10. Of course if the current code isn't broken in its use of ||, don't introduce a new bug by "fixing" it. ;)
Regular expressions are explained in perlre, perlrequick, perlretut, and perlop.
What constitutes true and false values is described in perlintro, perlsyn and perldata.
$customer ||= '';
is same as
$customer = $customer || '';
or
if (!$customer) { $customer = ""; }
### Code Here ###
use 5.012;
use warnings;
my #a = (1, 'Ah');
say (#a ~~ /^1$/ ? 'TRUE' : 'FALSE');
say ('1' ~~ #a ? 'TRUE' : 'FALSE');
say (#a ~~ "Ah" ? 'TRUE' : 'FALSE');
say (#a ~~ /^Ah$/ ? 'TRUE' : 'FALSE');
### STDOUT ###
TRUE
TRUE
FALSE
TRUE
Shouldn't all of these pass?
Smartmatch's behavior is generally determined by the type of the right operand; it's not symmetrical. Keep the array on the right side and you should see the behavior you expect.
From perlop:
It is often best read aloud as "in", "inside of", or "is contained in", because the left operand is often looked for inside the right operand. That makes the order of the operands to the smartmatch operand often opposite that of the regular match operator. In other words, the "smaller" thing is usually placed in the left operand and the larger one in the right.
Giving this a read over again, honestly the behavior seems a bit bizarre and unpredictable, and I'd limit my use of it to either well-documented helper functions or extremely trivial cases.
Smartmatch is a subtle beast, and the Perl5 implementation is arguably buggy – it was demoted to experimental status in the 5.18 release.
We can look at the table of possible type combinations to determine which case is chosen.
The #a ~~ /^1$/ has type ARRAY ~~ Regexp which has the description “any ARRAY elements match Regexp. Like: grep { /Regexp/ } ARRAY”.
The '1' ~~ #a has type Any ~~ ARRAY, which has the description “smartmatch each ARRAY element. Like: grep { Any ~~ $_ } ARRAY”. The second level of smart matches should use the Any ~~ Num and Any ~~ Any cases.
The #a ~~ "Ah" probably has type Any ~~ Any, which does string comparison!
The #a ~~ /^Ah$/ is the above regex case again.
The smartmatch table is best understood by looking at the right argument. If it is a collection, the smartmatch is an in operator. If it is a regex or a coderef, smartmatch behaves like an application. If it is a simple scalar, then a ordinary comparision (either == or eq) is done.
if (1=1)
then print "sdfsdfs" and print "sdfsdfsdfsdf"
else print "sdfsdf";
This gives an error. I want to do two things if the condition matches. How can I do that?
Parenthesize the commands and separate them with a semicolon:
if 1=1
then (print "sdfsdfs"; print "sdfsdfsdfsdf")
else print "sdfsdf"