See below for an update to the syntax for lambdas
Note: If you do not want to return something from your lambda, you should use Procedures$ProcedureX where X is the number of arguments.
The example lambda on the OH 1 wiki is overly complex and as written will not work in OH 2. This quick example will show a super simple lambda example with copious notes.
Here is the code without comments. It takes in an Item, logs it’s state and returns a slightly modified version of the String logged.
import org.eclipse.xtext.xbase.lib.* val Functions$Function1 log= [ GenericItem s | logInfo("lambda", s.state.toString) s.state.toString + " logged" ] rule "Call Lambda" when // some trigger then val loggedStr = log.apply(MyItem) end
Now with explanation.
// You must import the lambda classes. ESH Designer will say importing classes like this // is deprecated but I've found no workable alternative yet // See below for the workable alternative import org.eclipse.xtext.xbase.lib.* // A lambda is a global variable. I use a val to make it a constant. // // There are seven versions of Functions$FunctionN where N is from 0 to 6. The number // represents the number of arguments that are passed to the lambda. Thus, there is a limit // of up to six arguments for lambdas. // // Lambdas have absolutely no context. Any other global vars or vals (including other lambdas) // must be passed in as an argument. Lambdas do have access to Actions and all your Items // though so those do not necessarily need to be passed in. // // In the below there is a function that takes one GenericItem as its argument. Unlike the wiki // example, there is no need to use the fully qualified class name and in fact, because all the // core classes have moved to the Eclipse SmartHome packages the code on the wiki will not // work in OH 2. val Functions$Function1 log= [ GenericItem s | // log the passed in Item's state. Note we did not have to pass in the logInfo Action logInfo("lambda", s.state.toString) // The result from the last line of the lambda will be returned. // // If you have a lambda that doesn't cause any side effects (Designer will complain as such) // you can address the problem by putting "true" as the last line of the lambda. s.state.toString + " logged" ] // Some rule that uses the lambda. It isn't worth writing a lambda if you do not have more // than one rule the does the same thing. rule "Call Lambda" when // some trigger then // To call a lambda you use .apply and pass the arguments val loggedStr = log.apply(MyItem) end
For a potential alternative to lambdas in some circumstances see:
For those who have migrated to openHAB 2 and are using ESH Designer they may notice some warnings for all of the lambdas and the import line. If desired and if you do not want to have to cast things, particularly the return type, you can use the following syntax. The code below is the same as above using the new syntax. I removed the comments from above and added new ones to describe the new syntax.
// The Rules DSL has deprecated importing whole libraries using *, import those classes you actually // use individually. import org.eclipse.xtext.xbase.lib.Functions // Those who come from Java will recognize this syntax. The < > lets us define the types of the // arguments as well as the return value. If you plan on using this syntax make sure the last line in the // lambda matches the type of the last item in the < > // // You no longer need supply the types for the arguments (stuff before the |) val Functions$Function1<GenericItem, String> log= [ s | logInfo("lambda", s.state.toString) s.state.toString + " logged" ] rule "Call Lambda" when // some trigger then // In some cases you would have had to cast the result from the call to log to String, now that is not // needed val loggedStr = log.apply(MyItem) end