The first version make more sense to me. With the second version (6.4.1) two different facts will be equals (for exemple). Is it an error or did you do this on purpose ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I changed the code so that the subclasses of PrimitiveValue override the base methods for equal and hashCode, but it looks like I forgot to do this for the FactAddress, InstanceAddress, and ExternalAddress subclasses. I checked in some code to the svn repository to correct this.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Sorry to react so late, I had my own fix and was working on other points. I think there's still a problem with the equals method because you're using "==" on objects (e.g. Long) (which doesn't check the value of the object but the address). You should use ".equals" to get the desired behavior. Furthermore, in this case, it seems to me that the method definition could be in the parent class (PrimitiveValue) as its code doesn't change in any of it's subclasses :
I don't recall why I moved the equals code from the superclass to the subclasses, but use of == in the equals method is just applying reflexivity. An object is equal to itself, so if both objects compared have the same address, they're equal. Otherwise , the values of the object need to be compared. This was the most common design pattern I found when searching for implementing the equals method.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@TestpublicvoidreadTemplates()throwsException{finalEnvironmentclips=newEnvironment();finalStringclp="./src/test/resources/templates.clp";clips.load(ClipsFilePathConverter.getClipsPath(newFile(clp)));clips.eval("(init)");MultifieldValuefacts=(MultifieldValue)clips.eval("(get-fact-list *)");FactAddressValuef1=(FactAddressValue)facts.getValue().get(0);MultifieldValuefactsToo=(MultifieldValue)clips.eval("(get-fact-list *)");FactAddressValuef1Too=(FactAddressValue)factsToo.getValue().get(0);if(f1.equals(f1Too)){//<----IthinkitshouldbetrueSystem.out.println("f1 and f1Too are equals");}else{System.out.println("f1 and f1Too are not equals. Details :");System.out.println("f1.getValue() : "+f1.getValue());System.out.println("f1Too.getValue() : "+f1Too.getValue());booleanwitheqeq=f1.getValue()==f1Too.getValue();System.out.println("f1.getValue()==f1Too.getValue() : "+witheqeq);booleanwithequals=f1.getValue().equals(f1Too.getValue());System.out.println("f1.getValue().equals(f1Too.getValue()) : "+withequals);}}
I get this print result:
f1 and f1Too are not equals. Details :
f1.getValue() : 2281038163056
f1Too.getValue() : 2281038163056
f1.getValue()==f1Too.getValue() : false
f1.getValue().equals(f1Too.getValue()) : true
I expected an equality between facts "f1" and "f1Too". (With ".equals" instead of "==" in "equals" method it works as I expect).
Last edit: Chaubert Jérôme 2024-05-08
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
OK, I confused myself and thought the == you were referring to was in the code posted beneath your comments instead of the equals in the FactAddressValue class. Your fix corrects the issue. I'll check in fix for that shortly. I also was able to move a lot of the code back into the PrimitiveValue class. I think the reason I might have kept that code in the subclasses was because I was getting an unchecked cast warning from the MultifieldValue class when I cast the value from the PrimitiveValue superclass to a List<primitivevalue>, but everything seems to work correctly if I just store the value privately in the MultifieldValue class and override the equals method for just that class.</primitivevalue>
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
In Java class "PrimitiveValue" with Clips JNI 6.31. I have the following hashCode and equals (I honestly don't remember if it is my code or yours) :
But with Clips 6.4.1 I have these methods :
The first version make more sense to me. With the second version (6.4.1) two different facts will be equals (for exemple). Is it an error or did you do this on purpose ?
I changed the code so that the subclasses of PrimitiveValue override the base methods for equal and hashCode, but it looks like I forgot to do this for the FactAddress, InstanceAddress, and ExternalAddress subclasses. I checked in some code to the svn repository to correct this.
Perfect. Thank you. Can you tell me when it's done (I prefer to have as little difference as possible between our codes).
It's been checked in already: https://sourceforge.net/p/clipsrules/code/884/
Sorry to react so late, I had my own fix and was working on other points. I think there's still a problem with the equals method because you're using "==" on objects (e.g. Long) (which doesn't check the value of the object but the address). You should use ".equals" to get the desired behavior. Furthermore, in this case, it seems to me that the method definition could be in the parent class (PrimitiveValue) as its code doesn't change in any of it's subclasses :
Last edit: Chaubert Jérôme 2024-05-07
I don't recall why I moved the equals code from the superclass to the subclasses, but use of == in the equals method is just applying reflexivity. An object is equal to itself, so if both objects compared have the same address, they're equal. Otherwise , the values of the object need to be compared. This was the most common design pattern I found when searching for implementing the equals method.
Okay, but the behavior isn't what I expected.
With the following Clips code (in a file "templates.clp") :
and the following Java code :
I get this print result:
I expected an equality between facts "f1" and "f1Too". (With ".equals" instead of "==" in "equals" method it works as I expect).
Last edit: Chaubert Jérôme 2024-05-08
OK, I'll check that out.
OK, I confused myself and thought the == you were referring to was in the code posted beneath your comments instead of the equals in the FactAddressValue class. Your fix corrects the issue. I'll check in fix for that shortly. I also was able to move a lot of the code back into the PrimitiveValue class. I think the reason I might have kept that code in the subclasses was because I was getting an unchecked cast warning from the MultifieldValue class when I cast the value from the PrimitiveValue superclass to a List<primitivevalue>, but everything seems to work correctly if I just store the value privately in the MultifieldValue class and override the equals method for just that class.</primitivevalue>
I checked in a fix.
Thanks. It's perfect like that.