NAME

Locale::Unicode::RBNF::RuleSet - A rule set of a rule-based number format

VERSION

v0.1.0

DESCRIPTION

Internal module. This is a port of ICU4C NFRuleSet (nfrs.cpp, ICU 79.1).

CONVENTIONS

The methods follow the ICU code they are ported from, and share these arguments:

  • $st

    A scalar reference that receives an error status, the equivalent of ICU UErrorCode. It holds a message starting with the ICU error code name, such as U_PARSE_ERROR: .... Most methods do nothing if it is already set.

  • $out

    A scalar reference to the string being built by formatting.

  • $pos

    The position in $out where the text produced is inserted. Rules are formatted by inserting their text into the output, then the text of their substitutions at their own offsets.

  • $rc

    The recursion count, checked against $Locale::Unicode::RBNF::RuleSet::RECURSION_LIMIT (64), as ICU does, to stop runaway rule descriptions.

  • $pp

    A parse position, as an hash reference with the keys index and error, the equivalent of ICU ParsePosition.

  • $mask

    The bit mask of the non-numerical rules already executed during a parse, used by ICU to prevent infinite recursion through them.

CONSTANTS

The indices of the special rules in the array of non-numerical rules, as in ICU NFRuleSet: NEGATIVE_RULE_INDEX (0), IMPROPER_FRACTION_RULE_INDEX (1), PROPER_FRACTION_RULE_INDEX (2), DEFAULT_RULE_INDEX (3), INFINITY_RULE_INDEX (4), NAN_RULE_INDEX (5), and NON_NUMERICAL_RULE_LENGTH (6), the size of that array.

The variable $RECURSION_LIMIT is the maximum recursion depth of formatting and parsing, 64 as in ICU.

CONSTRUCTOR

new

my $rule_set = Locale::Unicode::RBNF::RuleSet->new( $formatter, \@descriptions, $index, \$st );

Takes the Locale::Unicode::RBNF object that owns the rule set, an array reference of rule set descriptions, the index of the description of this rule set, and a scalar reference that receives an error status.

The constructor only extracts the name of the rule set, such as %spellout-numbering, or %default if the description has none, and removes it from the description in the array. A name starting with %% makes the rule set private, and a name ending with @noparse makes it unparseable; that suffix is removed from the name. The rules themselves are parsed later by "parse_rules", once the names of all the rule sets are known, since rules can refer to any of them.

The formatter is kept as a weak reference.

METHODS

find_double_rule

my $rule = $rule_set->find_double_rule( $number );

This is ICU NFRuleSet::findDoubleRule(): it returns the rule to use for a double, that is the NaN, negative-number, infinity, fraction or default rule when applicable, or otherwise the normal rule for the number rounded to the nearest integer. In a fraction rule set, the rule giving the closest fraction is returned.

format_double

$rule_set->format_double( $number, $out, $pos, $rc, $st );

Formats a double with the rule returned by "find_double_rule". If the recursion limit is reached, $st is set to a U_INVALID_STATE_ERROR message.

format_int

$rule_set->format_int( $number, $out, $pos, $rc, $st );

Formats an integer with the normal rule applicable to it, found by binary search, honouring "should_roll_back" in Locale::Unicode::RBNF::Rule. If the recursion limit is reached, $st is set to a U_INVALID_STATE_ERROR message.

get_name

Returns the name of the rule set, including its leading % or %%.

get_owner

Returns the Locale::Unicode::RBNF object that owns the rule set.

is_fraction_rule_set

Returns true if the rule set is a fraction rule set, that is one used by a fractional part substitution such as >%%frac>, whose rules represent denominators.

is_named

my $bool = $rule_set->is_named( '%spellout-cardinal' );

Returns true if the rule set has the name given.

is_parseable

Returns true if the rule set takes part in parsing.

is_public

Returns true if the rule set is public, that is if its name does not start with %%.

make_into_fraction_rule_set

Marks the rule set as a fraction rule set. This is called by the fractional part substitutions that use it.

parse

my( $success, $value ) = $rule_set->parse( $text, $pp, $upper_bound, $mask, $rc );

This is ICU NFRuleSet::parse(): it matches the text against the non-numerical rules not yet executed according to $mask, then against the normal rules, from the most significant one, skipping, except in a fraction rule set, those whose base value is not below $upper_bound. It keeps the result of the rule that matched the most characters, and returns a list of 2 elements: whether something was matched, and the value parsed. $pp is updated with the position reached.

This method is provided by Locale::Unicode::RBNF::PP, and used by the pure Perl parsing engine.

parse_rules

$rule_set->parse_rules( $description, \$st );

This is ICU NFRuleSet::parseRules(): it divides the description into rules at the semicolons, creates them with "make_rules" in Locale::Unicode::RBNF::Rule, gives the rules without an explicit base value the base value of the preceding rule plus 1, or the same base value in a fraction rule set, and checks that the base values are in ascending order.

set_best_fraction_rule

$rule_set->set_best_fraction_rule( $index, $rule, $remember );

Determines the fraction rule to use at the given index of the non-numerical rules, when the rule set has several, such as x.x and x,x: the rule whose decimal point is the decimal separator of the decimal format symbols becomes the one in use. If $remember is true, the rule is also added to the list of fraction rules, so that the choice can be made again when the symbols change.

set_decimal_format_symbols

$rule_set->set_decimal_format_symbols( $symbols, \$st );

Passes new decimal format symbols to the rules, and selects again the fraction rules that match the new decimal separator, with "set_best_fraction_rule".

set_non_numerical_rule

$rule_set->set_non_numerical_rule( $rule );

Stores a non-numerical rule, that is a negative-number, fraction, default, infinity or NaN rule, at its index, according to its base value.

to_string

Returns the description of the rule set in the ICU syntax: its name followed by a colon, then each rule on its own line, as ICU NFRuleSet::appendRules() produces it. This is used by "rules" in Locale::Unicode::RBNF.

SEE ALSO

Locale::Unicode::RBNF, Locale::Unicode::RBNF::Rule, Locale::Unicode::RBNF::Substitution

AUTHOR

Jacques Deguest <jack@deguest.jp>

COPYRIGHT & LICENSE

Copyright(c) 2026 DEGUEST Pte. Ltd.

Portions are derived from ICU, Copyright (C) 2016 and later Unicode, Inc. and others, under the Unicode License (https://www.unicode.org/copyright.html). Its text is in the LICENSE-UNICODE file of this distribution.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.