I was attempting to do a nil check and then a method error check in a single if statement. Since the OR operator won't check any other conditions if the first one is true, I figured I could do something like this, to avoid nil pointer crashes and handle errors together:
if (uc.registry == nil) || (serviceName, err = uc.registry.GetServiceName(itemKind, key); err != nil) {}
This gives a syntax error, as it seems to try comparing the result of the first condition with the string value of serviceName.
Is it possible to do this?
Conditions must appear on the right-hand side of the ; if it is present, per the documentation. It is a shorthand for simple cases like error checks and map lookups. What you're doing would require two if statements.
Related
I have a text field in a table that contains JSON data as well as XML data. As I want to work with XML data only if it's valid XML, I want a way to make sure I can cast the string as XML without producing an error when '{"key":"val"}'::XML is possible.
Basically I want a function select isxml('{"key":"val"}) to return false, and select isxml('<key>1</key>') to be true.
I checked existing Postgres functions such as xml_is_well_formed, but they still return true when checking JSON strings. Maybe I can catch the error and deal with it in exceptions after a bad cast? Is there a good way to do this?
One possibility would be to use the xml_is_well_formed together with a function that checks whether or not the text content is a valid json. I.e.:
create or replace function is_valid_json(content text)
returns boolean
as
$$
begin
return (content::json is not null);
exception
when others then
return false;
end;
And in your query, you do [...] xml_is_well_formed(content) and not is_valid_json(content) [...].
My temporary solution is as follows
CREATE OR REPLACE FUNCTION isjson(p_json text)
RETURNS integer
LANGUAGE plpgsql
IMMUTABLE
AS $function$
begin
perform (p_json::json is not null);
return 1;
exception
when others then
return 0;
end;
$function$;
CREATE OR REPLACE FUNCTION isxml(p_xml text)
RETURNS boolean
LANGUAGE plpgsql
IMMUTABLE
AS $function$
BEGIN
PERFORM (p_xml::XML IS NOT NULL);
IF (xml_is_well_formed(p_xml)
AND NOT (CASE WHEN isjson(p_xml) = 1 THEN TRUE ELSE false END)
AND (SELECT p_xml ~ '^<.*>') )THEN -- regex matches <>, this may have uncovered edge cases
RETURN true;
ELSE
RETURN false;
END IF;
EXCEPTION
WHEN OTHERS THEN
RETURN false;
END;
$function$;
Note: my isjson function returns integer due to other legacy compatibility reasons, it would be easier to use boolean for this specific case. This should rule out most problematic cases but have lots of limitations in the regex used, accepting suggestions for improvement.
In all other programming languages I've encountered, if statements always require a boolean to work, however in Lua the following code does not contain any errors. What is being checked in this if statement if both true and false statements can't be made? How can you only check "if (variable) then"? I am new to programming and currently working with Roblox Studio, any help would be very appreciated.
function onTouched(Obj)
local h = Obj.Parent:FindFirstChild("Humanoid")
if h then
h.Health = 0
end
end
script.Parent.Touched:Connect(onTouched)
Most languages have their own rules for how values are interpreted in if statements.
In Lua, false and nil are treated as false. All other values are treated as true.
if h == nil (null)
So if it couldn't find a humanoid in the object that touched the script's parent, it will be false (null), otherwise true (not null).
So
if [ObjectName] then
equals to if [ObjectName] != null then
*Only valid for objects (non primitive values)
It's like that in script languages.
if h then end
is basically equivalent to
if h ~= nil and h ~= false then end
In Lua all values that are not nil or false are considered to be logically true.
if h then end is usually used to check wether h is not nil. So if code depends on wether h has been defined you put it in a condition like that.
In your example h is being index. indexing nil values is not allowed. So befor you index it you should make sure it isn't nil to avoid errors.
Checking return values of functions is good practice.
I'm trying to figure out mutual recursion. I have this code:
fun take(L)=
if L=nil then nil
else hd(L) :: skip(tl(L))
AND
fun skip(L)=
if L=nil then nil
else take(tl(L));
but it gives me these errors:
stdIn:54.14-54.18 Error: unbound variable or constructor: skip
stdIn:55.1-55.4 Error: unbound variable or constructor: AND
What am I doing wrong?
Your immediate error is because Standard ML is case-sensitive, and all of its reserved words are in lowercase; so you need to write and rather than AND.
Additionally, fun introduces an entire declaration, not an individual binding, meaning that you need to remove the extra fun after and.
Lastly, your functions currently require the list to have an equality type (such as int list or string list), which may not be a deal-breaker, but given what the functions actually do, there's really no reason they can't support non-equality types such as real list. To achieve that, you should match the parameter against the pattern nil, instead of testing whether the parameter equals nil. (More generally, you should use pattern-matching in more places; you have no reason to call hd and tl.)
Putting it together:
fun take nil = nil
| take (h::t) = h :: skip t
and skip nil = nil
| skip (h::t) = take t
my #g = (1,2,3,4);
say reduce {is-prime}, #g; # ==> gives error
say reduce {is-prime *}, #g; #==> gives error
say reduce {is-prime}, (1,2,3,4); # ==> gives error
say so is-prime #g.all; # ==> gives error
How to check if all elements of list are prime in Raku?
The answers above are all helpful, but they fail to explain why your solution does not work. Basically reduce is not going to apply a function (in your case, is-prime) to every member of a list. You want map for that. The error says
Calling is-prime() will never work with signature of the proto ($, *%)
Because reduce expects an infix, thus binary, function, or a function with two arguments; what it does is to apply them to the first pair of elements, then to the result and the third element, and so on. Last statement does not work for a similar reason: you are calling is-prime with a list argument, not a single argument.
You're basically asking: are there any elements in this list which are not prime? I would write that as:
say "not all prime" if #g.first: !*.is-prime;
Please note though, that apparently 1 is not considered prime according to the is-prime function:
say 1.is-prime; # False
so the first would trigger on the 1 in your example, not on the 4.
There are of course may ways to do this. A very explicit way is using a for loop:
for #g -> $g {
if $g.is-prime {
say $g;
}
}
Or with a grep (you could leave the $_ implicit):
#g.grep({ $_.is-prime }).say
Both above are assuming you really want to filter the primes out. Of course you can also really check each number and get a boolean:
#g.map({ .is-prime }).say
There is a big problem with this:
say reduce {is-prime}, #g;
You created a lambda:
{ }
The only thing it does is calls a function:
is-prime
You didn't give the function any arguments though.
Is it just supposed to guess what the arguments should be?
If you meant to pass in is-prime as a reference, you should have used &is-prime rather than {is-prime}.
Of course that still wouldn't have worked.
The other problem is that reduce operates by recursively combining values.
It can't do that if it operates on one argument at a time.
The bare block lambda {}, takes zero or one argument, not two or more.
reduce is often combined with map.
It happens so often that there is a Wikipedia page about MapReduce.
say ( map &is-prime, #g ==> reduce { $^a and $^b } );
# False
say ( map &is-prime, 2,3,5 ==> reduce { $^a and $^b } );
# True
I wrote it that way so that map would be in the line before reduce, but perhaps it would be more clear this way:
say reduce {$^a and $^b}, map &is-prime, 2,3,5;
# True
reduce with an infix operator is so common that there is a shorter way to write it.
say [and] map &is-prime, 2,3,5;
# True
Of course it would be better to just find the first value that isn't prime, and say the inverse.
Since if there is even a single value that isn't prime that would mean they can't all be primes.
You have to be careful though, as you may think something like this would always work:
not #g.first: !*.is-prime;
It does happen to work for the values you gave it, but may not always.
first returns Nil if it can't find the value.
not (2,3,5).first: !*.is-prime;
# not Nil === True
not (2,3,4).first: !*.is-prime;
# not 4 === False
not (2,3,0,4).first: !*.is-prime;
# not 0 === True
That last one returned 0 which when combined with not returns True.
You could fix this with defined.
not defined (2,3,0,4).first: !*.is-prime;
# False
This only works if first wouldn't return an undefined element that happens to be in the list.
(Int,Any).first: Real
# Int
defined (Int,Any).first: Real
# False
You could fix that by asking for the index instead of the value.
You of course still need defined.
(Int,Any).first: :k, Real
# 0
defined (Int,Any).first: :k, Real
# True
The other way to fix it is to just use grep.
not (2,3,0,4).grep: !*.is-prime;
# not (0,4) === False
Since grep always returns a List, you don't have to worry about checking for 0 or undefined elements.
(A List is True if it contains any elements, no matter what the values.)
grep is smart enough to know that if you coerce to Bool that it can stop upon finding the first value.
So it short-circuits the same as if you had used first.
This results in some fairly funky code, with those two negating operators. So it should be put into a function.
sub all-prime ( +#_ ) {
# return False if we find any non-prime
not #_.grep: !*.is-prime
# grep short-circuits in Bool context, so this will stop early
}
This could still fail if you give it something weird
all-prime 2,3,5, Date.today;
# ERROR: No such method 'is-prime' for invocant of type 'Date'
If you care, add some error handling.
sub all-prime ( +#_ ) {
# return Nil if there was an error
CATCH { default { return Nil }}
# return False if we find any non-prime
not #_.grep: !*.is-prime
}
all-prime 2,3,5, Date.today;
# Nil
use the all junction:
say so all #g».is-prime; # False
I am working with an .ado file named flow. If the user types flow i I want one if statement to run. If the user types flow e, I want another if statement to run.
How do I do this?
Many readers of this forum expect to see some code that you tried....
program flow
version 8 // will work on almost all Stata in current use
gettoken what garbage : 0
if "`what'" == "" | "`garbage'" != "" | !inlist("`what'", "e", "i") {
di as err "syntax is flow e or flow i"
exit 198
}
if "`what'" == "e" {
<code for e>
}
else if "`what'" == "i" {
<code for i>
}
end
The last if condition is redundant as we've already established that the user typed e or i. Edit it out according to taste.
Given your comment on the answer by #NickCox, I assume you tried something like this:
program flow
version 8
syntax [, i e]
if "`i'`e'" == "" {
di as err "either the i or the e option needs to be specified"
exit 198
}
if "`i'" != "" & "`e'" != "" {
di as err "the i and e options cannot be specified together"
exit 198
}
if "`e'" != "" {
<code for e>
}
if "`i'" != "" {
<code for i>
}
end
After that you call flow like this: flow, i or flow, e. Notice the comma, this is now necessary (but not in the command by #NickCox) because you made them options.
If you want i and e to be mutually exclusive options, then this is yet another alternative:
program flow
version 8
capture syntax , e
if _rc == 0 { // syntax matched what was typed
<code for e>
}
else {
syntax , i // error message and program exit if syntax is incorrect
<code for i>
}
end
If the code in each branch is at all long, many would prefer subprograms for each case as a matter of good style, but that would be consistent with the sketch here. Note that in each syntax statement the option is declared compulsory.
The effect of capture is this: errors are not fatal, but are "eaten" by capture. So you need to look at the return code, accessible in _rc. 0 for _rc always means that the command was successful. Non-zero always means that the command was unsuccessful. Here, and often elsewhere, there are only two ways for the command to be right, so we don't need to know what _rc was; we just need to check for the other legal syntax.
Note that even my two answers here differ in style on whether a user typing an illegal command gets an informative error message or just "invalid syntax". The context to this is an expectation that every Stata command comes with a help file. Some programmers write on the assumption that the help file explains the syntax; others want their error messages to be as helpful as possible.