Reputation: 4126
I would like to allow user to set a BigDecimal
property in my class using both BigDecimal
and String
(for backward compatibility reasons).
extension.timeoutFactor = 1.81
extension.timeoutFactor = "2.12"
It tried to use two setter with different parameter types:
class PitestPluginExtension {
BigDecimal timeoutFactor
void setTimeoutFactor(BigDecimal timeoutFactor) {
this.timeoutFactor = timeoutFactor
}
@Deprecated
void setTimeoutFactor(String timeoutFactor) {
//display deprecation warning
this.timeoutFactor = timeoutFactor.toBigDecimal()
}
}
but Groovy fails with:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object
'2.12' with class 'java.lang.String' to class 'java.math.BigDecimal'
If the setters are called directly everything work fine, but this is a Gradle plugin and people used to use property assignments.
Is it possible to tell Groovy (1.8.6) to use different input types on a property assignment (preferably without using Groovy meta programming)?
Upvotes: 0
Views: 733
Reputation: 4126
The following solution (hinted by @Don's answer!) seems to work because 1.21
as BigDecimal
is losslessly converted to String
and used in the setter. Later it can be get as BigDecimal
.
class PitestPluginExtension {
BigDecimal timeoutFactor
void setTimeoutFactor(String timeoutFactor) {
this.timeoutFactor = new BigDecimal(timeoutFactor)
}
}
def extension = new PitestPluginExtension()
extension.timeoutFactor = "1.81"
assert extension.timeoutFactor == 1.81
extension.timeoutFactor = 1.21
assert extension.timeoutFactor == 1.21
Upvotes: 0
Reputation: 187529
import java.math.*
class PitestPluginExtension {
private BigDecimal timeoutFactor
void setTimeoutFactor(timeoutFactor) {
this.timeoutFactor = new BigDecimal(timeoutFactor)
}
def getTimeoutFactor() {
this.timeoutFactor
}
}
// ignore differences due to precision errors
void compareImprecisely(BigDecimal expected, BigDecimal actual) {
BigDecimal roundedExpected = Math.round(expected * 100) / 100
BigDecimal roundedActual = Math.round(actual * 100) / 100
assert roundedExpected == roundedActual
}
def ppe = new PitestPluginExtension()
def expected = new BigDecimal('1.11')
// test assigning a string
ppe.timeoutFactor = '1.11'
compareImprecisely expected, ppe.timeoutFactor
// test assigning a BigDecimal
ppe.timeoutFactor = 1.11
compareImprecisely expected, ppe.timeoutFactor
Upvotes: 2