1

我有一个正在生成的字符串传递给模板工具包并由模板工具包输出,使用:

https://metacpan.org/module/Template::Plugin::Number::Format

format_price如果它们为零,我想从价格中降低美分。所以 100.00 变成 100

找不到任何明确的解决方案。

更新:

format_price在这个项目的数百个地方使用,如果可能的话,我不想改变它,如果可能的话,用这个功能覆盖方法。

4

3 回答 3

2

您可以扩展Template::Plugin::Number::Format以创建自己的插件,如下所示:

package Template::Plugin::My::Number::Format;
use base qw(Template::Plugin::Number::Format);
use Number::Format;

sub init {
    my ($self, $config) = @_;
    $self->SUPER::init($config);
    my $nfo = Number::Format->new(%$config);
    $self->{ _CONTEXT }->define_filter(format_price => sub {
        my ($context, @args) = @_;
        return sub {
            my $text = shift;
            my $result = $nfo->format_price($text, @args);
            $result =~ s/\.00$//;
            return $result;
        };
    }, 1);
    return $self;
}

然后在您的模板中,您将像这样使用您的插件:

[% USE My.Number.Format %]
...
[% some_number | format_price %]
于 2013-02-06T22:28:26.233 回答
1

实现此函数的覆盖以按照您的需要运行应该相对简单。

插件代码的作用几乎是微不足道的。从您安装它的任何地方获取它的副本并使其成为您的代码库的一部分,因此您的版本是在编译期间将找到的版本,即

Myapp/lib/Template/Plugin/Number/Format.pm

编辑它:

-use Number::Format;
+use Number::Format::NoZeroCents;

然后在您的代码中添加一个新模块:

Myapp/lib/Number/Format/NoZeroCents.pm;

看起来像这样:

package Number::Format::NoZeroCents;

use strict;
use warnings;

use base 'Number::Format';

sub format_price {
    my $self = shift;
    my ($number, $precision, $symbol) = @_;
    if(defined $precision){ #default behaviour
        printf STDERR "%s: default behaviour for %s\n", __PACKAGE__, join(';',@_);
        return $self->SUPER::format_price(@_)
    }
    else {
        $precision = 0 if $number == int($number);
        printf STDERR "%s: override behaviour for %s\n", __PACKAGE__, $number;
        return $self->SUPER::format_price($number, $precision, $symbol)
    }
}

1;

这应该意味着您的 NoZeroCents 方法在您的代码中默认使用,但是[% number | format_price(2) %]当您希望出现 $100.00 时,您可以通过调用来覆盖。


更新

Number::Format 在被告知使用精度 => 0 时肯定是正确的,因为这个快速测试证实:

#!/usr/bin/env perl

use strict;
use warnings;

use Number::Format qw(format_price);

my $v = 100.00;

printf "Original value as string '%s'; as number '%f'; as fp '%s'; as fp0: '%s'\n",
       $v, $v, format_price($v), format_price($v,0);

产生:

Original value as string '100'; as number '100.000000'; as fp 'AUD 100.00'; as fp0: 'AUD 100'
于 2013-02-05T05:15:19.297 回答
0

看起来额外的零特别适用于货币模式。

format_price($precision) 返回一个包含 "$number" 的字符串,其格式类似于 "format_number()",除了小数部分可能添加尾随零以使其正好是 "$precision" 字符长,货币字符串将为前缀。

如果你仍然想避免它,我想不使用这种模式就足够了

于 2013-02-05T01:22:21.153 回答