-
Notifications
You must be signed in to change notification settings - Fork 337
Making my class/module "string-like" #1122
-
I am trying to ensure that my implementation of a module I am working on for representing decimal numbers outputs as a string in all formats. I've tried defining output in the module but it is not working, unless I directly evalaluate the module or use an expression like this:
pkl eval pkl/lib/Decimal.pkl -f json -x 'Decimal.parse("2.0")'
But if I use Decimal as a type elsewhere it outputs as an object with a value like this:
{
"apr":
}// Decimal.pkl module com.capitalone.cpm.Decimal import "Decimal.pkl" hidden const DECIMAL_STRING_REGEX = Regex(#"^(-?\d+)(\.\d+)?$"#) /// Parse a decimal string into a Decimal object. function parse(decimalString: DecimalString): Decimal = let (parts = decimalString.split(".")) let (hasDecimal = parts.length > 1) let (integerPart = parts[0]) let (fractionalPart = if (hasDecimal) parts[1] else "") let (significandStr = integerPart + fractionalPart) new Decimal { significand = significandStr.toInt() precision = significandStr.length scale = fractionalPart.length } hidden significand: Int hidden precision: Int(this > 0) hidden scale: Int(this >= 0 && this <= precision) fixed value = toString() function toFloat(): Float = significand.toFloat() / (10 ** scale) function toString(): DecimalString = if (scale == 0) significand.toString() else let (significandStr = significand.toString()) let (splitIndex = significandStr.length - scale) if (splitIndex <= 0) let (leadingZeros = "0".repeat(1 - splitIndex)) "0.\(leadingZeros)\(significandStr)" else let (integerPart = significandStr.substring(0, splitIndex)) let (fractionalPart = significandStr.substring(splitIndex, significandStr.length)) "\(integerPart).\(fractionalPart)" typealias DecimalString = String(matches(DECIMAL_STRING_REGEX)) output { value = toString() }
Beta Was this translation helpful? Give feedback.
All reactions
In this case you would need to use an output converter (in the/each module being evaluated) to convert Decimal values to strings:
output { renderer { converters { [Decimal] = (it) -> it.toString() } } }
Note that this is inherited when amending modules.
Also, the toString() method is implicitly called when interpolating values into strings, eg.
decimalString = "\(someDecimalValue)"
It's also worth noting #923 as a gotcha; this doesn't currently apply when joining Lists/Listings.
Replies: 1 comment 1 reply
-
In this case you would need to use an output converter (in the/each module being evaluated) to convert Decimal values to strings:
output { renderer { converters { [Decimal] = (it) -> it.toString() } } }
Note that this is inherited when amending modules.
Also, the toString() method is implicitly called when interpolating values into strings, eg.
decimalString = "\(someDecimalValue)"
It's also worth noting #923 as a gotcha; this doesn't currently apply when joining Lists/Listings.
Beta Was this translation helpful? Give feedback.
All reactions
-
Thank you.
Beta Was this translation helpful? Give feedback.