[
https://issues.apache.org/jira/browse/FREEMARKER-169?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Andrew Cook updated FREEMARKER-169:
-----------------------------------
Description:
While trying to build a custom template number formatter, I've encountered
various inconsistencies around the C builtin, C NumberFormat, and related
documentation.
Description follows.
h2. c built-in Behavior
My use case requires XML compatible NaN/INF representations, and rather than
write the string format representation logic myself, I wanted to leverage the
logic used for the c built-in, since the [c-builtin
documentation|https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_c]
states that "[i]f the {{incompatible_improvements}} FreeMarker configuration
setting is set to 2.3.24 or higher (also if it's set to 2.3.20 or higher and
you are outside a string literal), this built-in will return {{"INF"}},
{{"-INF"}} and {{"NaN"}} for positive/negative infinity and IEEE floating point
Not-a-Number, respectively."
In my project, we have {{incompatible_improvements}} version set to 2.3.29:
{code:java}
cfg = new Configuration(Configuration.VERSION_2_3_29);
{code}
So the expected behavior for the c-builtin is that INF, -INF, and NaN are
represented as such, and it does, with val=Double.POSITIVE_INFINITY in the root
context:
{code:java}
<MyDocument>
<myField>${val?c}</myField>
</MyDocument>{code}
Yields:
{code:java}
<MyDocument>
<myField>INF</myField>
</MyDocument>{code}
Great, just what I want.
h2. CNumberFormat Behavior Mismatch
To access this behavior for my custom template number format, I tried to use
[Environment::getCNumberFormat|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/Environment.java#L1473]
since it's documentation says that it "[r]eturns the NumberFormat used for the
c built-in." Again, that should be great, since the c built-in has exactly the
behavior I want.
Went I implemented this and made a test, however, this code:
{code:java}
environment.getCNumberFormat().format(Double.POSITIVE_INFINITY);
{code}
Returned "∞". Not if you look at [the
code|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/Environment.java#L1477]
because under the hood, this ended up returning [a DecimalFormat
object|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/Environment.java#L104],
contra was is suggested by the various documentation, including, for the c
built-in: "[e]arlier it has returned what {{java.text.DecimalFormat}} did with
US locale, none of which is understood by any (common) computer language." It
seems like it actually still just returns DecimalFormat in some cases.
h2. string.computer Behavior Mismatch
Further inconsistency comes in with the string.computer builtin. The [string
builtin for numbers
documentation|https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_string_for_number]
states that "[t]here are four predefined number formats: {{computer}},
{{currency}}, {{number}}, and {{percent}}. The exact meaning of these is locale
(nationality) specific, and is controlled by the Java platform installation,
not by FreeMarker, except for {{computer}}, which uses the same formatting as
[the {{c}}
built-in|https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_c]."
So the expected behavior of the following should be the same as my use of the c
built-in above:
{code:java}
<MyDocument>
<myField>${val?string.computer}</myField>
</MyDocument>
{code}
But it's not:
{code:java}
<MyDocument>
<myField>∞</myField>
</MyDocument>
{code}
The cause for this is the same as the cause of the other inconsistency, since
it seems that the computer number format for the string builtin for numbers
[just uses
Environment::getCNumberFormat|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/JavaTemplateNumberFormatFactory.java#L58],
which as I've already mentioned has the same problem.
h2. Conclusion
Either documentation in multiple places is wrong and should be updated or the
implementation for all this is wrong because the formatting logic isn't shared
(as, indeed, it isn't, since [the c built-in works totally
differently|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java#L94]).
Please either update the documentation or the implementation to resolve these
inconsistencies. It was quite confusing for me and took a good bit of digging
to figure out what was going on.
Let me know if you need any other information
was:
While trying to build a custom template number formatter, I've encountered
various inconsistencies around the C builtin, C NumberFormat, and related
documentation.
I'll explain the problems below.
h2. c built-in Behavior
My use case requires XML compatible NaN/INF representations, and rather than
write the string format representation logic myself, I wanted to leverage the
logic used for the c built-in, since the [c-builtin
documentation|https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_c]
states that "[i]f the {{incompatible_improvements}} FreeMarker configuration
setting is set to 2.3.24 or higher (also if it's set to 2.3.20 or higher and
you are outside a string literal), this built-in will return {{"INF"}},
{{"-INF"}} and {{"NaN"}} for positive/negative infinity and IEEE floating point
Not-a-Number, respectively."
In my project, we have {{incompatible_improvements}} version set to 2.3.29:
{code:java}
cfg = new Configuration(Configuration.VERSION_2_3_29);
{code}
So the expected behavior for the c-builtin is that INF, -INF, and NaN are
represented as such, and it does, with val=Double.POSITIVE_INFINITY in the root
context:
{code:java}
<MyDocument>
<myField>${val?c}</myField>
</MyDocument>{code}
Yields:
{code:java}
<MyDocument>
<myField>INF</myField>
</MyDocument>{code}
Great, just what I want.
h2. CNumberFormat Behavior Mismatch
To access this behavior for my custom template number format, I tried to use
[Environment::getCNumberFormat|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/Environment.java#L1473]
since it's documentation says that it "[r]eturns the NumberFormat used for the
c built-in." Again, that should be great, since the c built-in has exactly the
behavior I want.
Went I implemented this and made a test, however, this code:
{code:java}
environment.getCNumberFormat().format(Double.POSITIVE_INFINITY);
{code}
Returned "∞". Not if you look at [the
code|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/Environment.java#L1477]
because under the hood, this ended up returning [a DecimalFormat
object|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/Environment.java#L104],
contra was is suggested by the various documentation, including, for the c
built-in: "[e]arlier it has returned what {{java.text.DecimalFormat}} did with
US locale, none of which is understood by any (common) computer language." It
seems like it actually still just returns DecimalFormat in some cases.
h2. string.computer Behavior Mismatch
Further inconsistency comes in with the string.computer builtin. The [string
builtin for numbers
documentation|https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_string_for_number]
states that "[t]here are four predefined number formats: {{computer}},
{{currency}}, {{number}}, and {{percent}}. The exact meaning of these is locale
(nationality) specific, and is controlled by the Java platform installation,
not by FreeMarker, except for {{computer}}, which uses the same formatting as
[the {{c}}
built-in|https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_c]."
So the expected behavior of the following should be the same as my use of the c
built-in above:
{code:java}
<MyDocument>
<myField>${val?string.computer}</myField>
</MyDocument>
{code}
But it's not:
{code:java}
<MyDocument>
<myField>∞</myField>
</MyDocument>
{code}
The cause for this is the same as the cause of the other inconsistency, since
it seems that the computer number format for the string builtin for numbers
[just uses
Environment::getCNumberFormat|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/JavaTemplateNumberFormatFactory.java#L58],
which as I've already mentioned has the same problem.
h2. Conclusion
Either documentation in multiple places is wrong and should be updated or the
implementation for all this is wrong because the formatting logic isn't shared
(as, indeed, it isn't, since [the c built-in works totally
differently|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java#L94]).
Please either update the documentation or the implementation to resolve these
inconsistencies. It was quite confusing for me and took a good bit of digging
to figure out what was going on.
Let me know if you need any other information
> Various inconsistencies around c builtin
> ----------------------------------------
>
> Key: FREEMARKER-169
> URL: https://issues.apache.org/jira/browse/FREEMARKER-169
> Project: Apache Freemarker
> Issue Type: Bug
> Affects Versions: 2.3.29
> Environment: OS: Ubuntu 20.04.1 LTS (virtual machine)
> Hardware: 32GB; 6 core processor (virtual machine)
> Java Version: 1.8.0_172
> Reporter: Andrew Cook
> Priority: Minor
>
> While trying to build a custom template number formatter, I've encountered
> various inconsistencies around the C builtin, C NumberFormat, and related
> documentation.
> Description follows.
> h2. c built-in Behavior
> My use case requires XML compatible NaN/INF representations, and rather than
> write the string format representation logic myself, I wanted to leverage the
> logic used for the c built-in, since the [c-builtin
> documentation|https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_c]
> states that "[i]f the {{incompatible_improvements}} FreeMarker configuration
> setting is set to 2.3.24 or higher (also if it's set to 2.3.20 or higher and
> you are outside a string literal), this built-in will return {{"INF"}},
> {{"-INF"}} and {{"NaN"}} for positive/negative infinity and IEEE floating
> point Not-a-Number, respectively."
> In my project, we have {{incompatible_improvements}} version set to 2.3.29:
> {code:java}
> cfg = new Configuration(Configuration.VERSION_2_3_29);
> {code}
> So the expected behavior for the c-builtin is that INF, -INF, and NaN are
> represented as such, and it does, with val=Double.POSITIVE_INFINITY in the
> root context:
> {code:java}
> <MyDocument>
> <myField>${val?c}</myField>
> </MyDocument>{code}
> Yields:
> {code:java}
> <MyDocument>
> <myField>INF</myField>
> </MyDocument>{code}
> Great, just what I want.
> h2. CNumberFormat Behavior Mismatch
> To access this behavior for my custom template number format, I tried to use
> [Environment::getCNumberFormat|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/Environment.java#L1473]
> since it's documentation says that it "[r]eturns the NumberFormat used for
> the c built-in." Again, that should be great, since the c built-in has
> exactly the behavior I want.
> Went I implemented this and made a test, however, this code:
>
> {code:java}
> environment.getCNumberFormat().format(Double.POSITIVE_INFINITY);
> {code}
> Returned "∞". Not if you look at [the
> code|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/Environment.java#L1477]
> because under the hood, this ended up returning [a DecimalFormat
> object|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/Environment.java#L104],
> contra was is suggested by the various documentation, including, for the c
> built-in: "[e]arlier it has returned what {{java.text.DecimalFormat}} did
> with US locale, none of which is understood by any (common) computer
> language." It seems like it actually still just returns DecimalFormat in some
> cases.
>
> h2. string.computer Behavior Mismatch
> Further inconsistency comes in with the string.computer builtin. The [string
> builtin for numbers
> documentation|https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_string_for_number]
> states that "[t]here are four predefined number formats: {{computer}},
> {{currency}}, {{number}}, and {{percent}}. The exact meaning of these is
> locale (nationality) specific, and is controlled by the Java platform
> installation, not by FreeMarker, except for {{computer}}, which uses the same
> formatting as [the {{c}}
> built-in|https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_c]."
> So the expected behavior of the following should be the same as my use of the
> c built-in above:
>
> {code:java}
> <MyDocument>
> <myField>${val?string.computer}</myField>
> </MyDocument>
> {code}
> But it's not:
>
>
> {code:java}
> <MyDocument>
> <myField>∞</myField>
> </MyDocument>
> {code}
> The cause for this is the same as the cause of the other inconsistency, since
> it seems that the computer number format for the string builtin for numbers
> [just uses
> Environment::getCNumberFormat|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/JavaTemplateNumberFormatFactory.java#L58],
> which as I've already mentioned has the same problem.
> h2. Conclusion
> Either documentation in multiple places is wrong and should be updated or the
> implementation for all this is wrong because the formatting logic isn't
> shared (as, indeed, it isn't, since [the c built-in works totally
> differently|https://github.com/apache/freemarker/blob/v2.3.29/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java#L94]).
> Please either update the documentation or the implementation to resolve these
> inconsistencies. It was quite confusing for me and took a good bit of digging
> to figure out what was going on.
> Let me know if you need any other information
>
>
--
This message was sent by Atlassian Jira
(v8.3.4#803005)