Class simulation in rules

Hi community,
from my understanding classes are not available in rules. Therefore I’m using a HashMap of <key>,<Object> pairs to store a collection of Objects, like:

"obj01_propertyA" -> GenericItem
"obj01_propertyB" -> GenericItem
"obj01_propertyC" -> Number
"obj02_propertyA" -> GenericItem
...

This simulates a collection of objects of a class containing 3 poperties of different data types. Then I use lambda functions to build the relative methods for creating a new object or disposing it.
So my code looks like this:

val HashMap<String, Object> myObjs = new HashMap

val Functions$Function4<Map<String, Object>, GenericItem, GenericItem, Number, Boolean> myObj_create = [
    objMap,
    myItem1,
    myItem2,
    theNumber |

    var String itemKey = myItem1.name
    objMap.put(itemKey + "_propertyA", myItem1)
    objMap.put(itemKey + "_propertyB", myItem2)

    var Number nTmp = new Number
    nTmp = theNumber
    objMap.put(itemKey + "_propertyC", nTmp)

    return true
    ]

Item objects are pointers to objects, so I don’t need to create copies of them to put into the HashMap. But when it comes to the Number object, I think I cannot directly add the incoming parameter theNumber to the HashMap, because once exited from the function it doesn’t exist anymore. Then I decided to create a new Number but I get the follwoing error

Could not invoke constructor: java.lang.Number.Number()

What is it that I’m doing wrong?
thanks.

Why are you not doing this?

    var Number nTmp = theNumber

I think this will create a local variable nTmp. If I store the local variable in the HashMap I actually store the pointer to the local variable. But when I exit the function that nTmp doesn’t exist anymore and the pointer inside the HashMap would point to a disposed memory variable.

Am I wrong? (sorry I’m an old C programmer getting to know Java right now).

No idea. What you said above makes absolutely no sense to me. You might as well have been speaking chinese.

Let’s go back to the start.
Why are going going through such complicated length?
What is the purpose of this “Class”?
This can probably be avoided by using group: Design Pattern: Working with Groups in Rules

Thank you. I read through the tutorial but I think the purpose is different. In the tutorial the need is grouping together objects of the same type. My aim is grouping objects of different types.

I’m building a widget for timed switches. I want a widget which, once activated, changes the state of a switch, starts a timer and shows a countdown. At the end of the countdown the switch is toggled back to it’s initial state (for example: switch on lights for 90 seconds).
I need few objects to manage the timer, the countdown the switch and the triggering switch, which I’d like to group together as they were a class.

…if we had classess we wouldn’t need this complexity, hopefully they will be introduced in later releases. :slight_smile:

Again, anyone suggesting how can I .put a Number in a

HashMap<String>,<Object>

?

thanks.

They won’t. The language don’t allow them
Have you looked at JS and Jython as alternative scripting languages. There are chapters in the docs and threads on the subject in the forum

There are several ways to handle this. A HashMap is probably the worst or the options. Don’t try to simulate objects or other programming concepts in Rules DSL using maps and lambdas. You will end up with long, brittle, and ugly code.

You need to either change your approach to one that is better for us in Rules DSL or user a different language (jsr223) which let’s you write rules in jython, JavaScript, or Groovy.

A more Rules DSL approach would be Design Pattern: Associated Items.

You can also use Item metadata (I don’t have any experience with this but it is possible to set and access values on an item from rules. I think you need to be on a snapshot though.

Number is an interface, not a class. You can’t instantiate a Number, you have to instantiate a class that implements Number like BigDecimal or Integer.

Yes, you are wrong. Melts manager doesn’t work like that. If you have the referent to the local variable to the map, then that variable will continue to exist until it is removed from the map too.

In Java, Rules DSL, and almost every modern language a variable continues to exist until they’re are no more pointers to it. Then it gets garbage collected.

And while Rules DSL runs on top of the Java Virtual Machine and it has access to Java libraries, it is not Java. Far from it in fact.

That isn’t the purpose of that DP. The DP is about tagging Items that after related to each other and the operations you can do on those groups of Items. There is nothing that states that they have to be of the same type.

Unless I’m mistaken, none of the data you would save to the HashMap would be available to the widget anyway. Variables inside Rules are only available to the rules in that one .rules file. So this approach, and classes for that matter, was never going to work.

Never going to happen. Classes were deliberately left out of the Rules DSL. The Rules DSL is in the pieces of being replaced. And the availability of classes would help your makes a UI widget anyway.

If you want classes for other reasons, you can and should use JSR223.

For one thing the syntax is wrong.

Val Map<String, Object> myMap = newHadhMap

Then, as I said above, you can instantiate a Number. You have to instantiate a class that implements Number. Once you have that you can guest call put.

@vzorglub, this is actually a good example of the be XYProblem I think.

Understood, thanks for the detailed explanation. I don’t need the new.

I knew this: variables that must be accessed by the widget are defined as items, put in the HashMap and updated via postUpdate.

this was my first thought. I tryed to get to 2.4.0M5 (which would solve another couple of issues) but I got too many errors in the log and rolled back (I’m just a beginner and I’m sure I have done something wrong).

This sounds really good, I’ll finish my code and then think about converting to this tecnique.

Thanks.