KRL: if then else problems
I am trying to write something comparable to an If, else if, else statement. However, the online compiler is giving me problems.
I usually write my code in jquery and just emit it... but I am trying to do it the KRL way this time and I am running into problems.
When I write something like the following (between the Pre and Post blocks), I get compiler errors:
if (someEx开发者_JAVA百科pression) then { //Do some code } else { //DO some code }
I know that there is a reason... but I need someone to explain it to me... or point me to the documentation.
With KRL, it's often best to have separate rules to handle the "if...then" and "else" cases described in your question. That's simply because it's a rule language; you kind of have to change your way of thinking about the problem from the usual procedural way of doing it.
That said, Mike's suggestion to raise explicit events is usually the best way to solve the problem. Here's an example:
ruleset a163x47 {
meta {
name "If-then-else"
description <<
How to use explicit events to simulate if..then..else behavior in a ruleset.
>>
author "Steve Nay"
logging off
}
dispatch { }
global { }
rule when_true {
select when web pageview ".*"
//Imagine we have an entity variable that tracks
// whether the user is logged in or not
if (ent:logged_in) then {
notify("My app", "You are already logged in");
}
notfired {
//This is the equivalent of an else block; we're sending
// control to another rule.
raise explicit event not_logged_in;
}
}
rule when_false {
select when explicit not_logged_in
notify("My app", "You are not logged in");
}
}
In this simple example, it would also be easy enough to write two rules that are the same except that one has a not
in the if
statement and the other does not. That accomplishes the same purpose:
if (not ent:logged_in) then {
There is more documentation about the postlude (fired
and notfired
, for example), on Kynetx Docs. I also like the more extensive example that Mike wrote on Kynetx App A Day.
You can use ternary operators in the pre block for variable assignment as illustrated at http://kynetxappaday.wordpress.com/2010/12/21/day-15-ternary-operators-or-conditional-expressions/
You can also conditionally raise explicit events based on whether the action block fired or not as illustrated at http://kynetxappaday.wordpress.com/2010/12/15/day-6-conditional-action-blocks-and-else-postludes/
Here is some code posted by Sam, that explains how to use defactions to mimic an ifthenelse behavior. All this credit for this genius belongs to Sam Curren. This is probably the best answer you could get.
ruleset a8x152 {
meta {
name "if then else"
description <<
Demonstrates the power of actions to enable 'else' in krl!
>>
author "Sam Curren"
logging off
}
dispatch {
// Deploy via bookmarklet
}
global {
ifthenelse = defaction(cond, t, f){
a = cond => t | f;
a();
};
}
rule first_rule {
select when pageview ".*" setting ()
pre {
testcond = ent:counter % 2 == 1;
}
ifthenelse(
testcond,
defaction(){notify("test","counter odd!");},
defaction(){notify("test","counter even!");}
);
always {
ent:counter += 1 from 1;
}
}
}
精彩评论