Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qute: if section - adjust the evaluation rules for equality operators #44615

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mkouba
Copy link
Contributor

@mkouba mkouba commented Nov 21, 2024

@mkouba
Copy link
Contributor Author

mkouba commented Nov 21, 2024

@neon-dev Hopefully this makes a little bit more sense.

Comment on lines +495 to +508
boolean equals(Object op1, Object op2) {
if (op1 == op2) {
return true;
}
if (op1 != null && op2 != null && (op1 instanceof Number || op2 instanceof Number)) {
if (op1.getClass().equals(op2.getClass())) {
// Both operands are of the same Number type
return op1.equals(op2);
}
// Both operands are not null and at least one of them is a number
return getDecimal(op1).compareTo(getDecimal(op2)) == 0;
}
return Objects.equals(op1, op2);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks a lot!

Just one question:
Couldn't the following code be simplified like so?

Suggested change
boolean equals(Object op1, Object op2) {
if (op1 == op2) {
return true;
}
if (op1 != null && op2 != null && (op1 instanceof Number || op2 instanceof Number)) {
if (op1.getClass().equals(op2.getClass())) {
// Both operands are of the same Number type
return op1.equals(op2);
}
// Both operands are not null and at least one of them is a number
return getDecimal(op1).compareTo(getDecimal(op2)) == 0;
}
return Objects.equals(op1, op2);
}
boolean equals(Object op1, Object op2) {
if (Objects.equals(op1, op2)) {
return true;
}
if (op1 instanceof Number && op2 instanceof Number) {
return getDecimal(op1).compareTo(getDecimal(op2)) == 0;
}
return false;
}

This check would not throw a TemplateException if only one of the operands is instanceof Number, which may or may not be wanted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm yes, well, your proposal is not functionally equivalent. The current version allows for comparison of e.g. String and Integer. Also op1 == op2 should be, in theory, more effective than equals(). In other words, we only want to call equals unless the objects are identical or number comparison is possible. Does that make sense?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current version allows for comparison of e.g. String and Integer.

Oh yeah, I completely missed that. So {#if 0 == "0"} should be true if I understand correctly?

we only want to call equals unless the objects are identical or number comparison is possible

Objects.equals is implemented as (a == b) || (a != null && a.equals(b));, so we would only see unnecessary .equals calls for two objects of different Number types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current version allows for comparison of e.g. String and Integer.

Oh yeah, I completely missed that. So {#if 0 == "0"} should be true if I understand correctly?

Yes, I think so. We do the same for comparison operators such as >; e.g. {#if 10 > "1"} should be also true.

we only want to call equals unless the objects are identical or number comparison is possible

Objects.equals is implemented as (a == b) || (a != null && a.equals(b));, so we would only see unnecessary .equals calls for two objects of different Number types.

Yes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. So this would be functionally equivalent, but maybe not much of an improvement anymore:

boolean equals(Object op1, Object op2) {
    if (Objects.equals(op1, op2)) {
        return true;
    }
    if (op1 != null && op2 != null && (op1 instanceof Number || op2 instanceof Number)) {
        return getDecimal(op1).compareTo(getDecimal(op2)) == 0;
    }
    return false;
}

Copy link

github-actions bot commented Nov 21, 2024

🎊 PR Preview 16759d4 has been successfully built and deployed to https://quarkus-pr-main-44615-preview.surge.sh/version/main/guides/

  • Images of blog posts older than 3 months are not available.
  • Newsletters older than 3 months are not available.

This comment has been minimized.

Copy link

quarkus-bot bot commented Nov 21, 2024

Status for workflow Quarkus Documentation CI

This is the status report for running Quarkus Documentation CI on commit 3e49c8c.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

Warning

There are other workflow runs running, you probably need to wait for their status before merging.

Copy link

quarkus-bot bot commented Nov 21, 2024

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit 3e49c8c.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Qute: Unexpected primitive equality
3 participants