有这个代码
use 5.034;
use warnings;
#use utf8;
binmode(STDOUT, ':encoding(utf-8)');
package User {
use Method::Signatures::Simple;
use Moose;
has 'name' => (is => 'rw', isa => 'Str', default => sub { return 'foo' });
method xname { return "čč" . $self->name . "ňň"; }
}
my $u = User->new;
say $u->xname;
它几乎按预期工作(不完全正确,因为源代码包含 utf8。)
取消注释
use utf8;
后,perl -c
会抛出错误:
Couldn't find declarator 'method' at /u/ae/envs/plenv/versions/5.38.2/lib/perl5/site_perl/5.38.2/amd64-freebsd/Devel/Declare/Context/Simple.pm line 47.
Devel::Declare::Context::Simple::skip_declarator(Method::Signatures::Simple=HASH(0x8292a3fa8)) called at /u/ae/envs/plenv/versions/5.38.2/lib/perl5/site_perl/5.38.2/amd64-freebsd/Devel/Declare/MethodInstaller/Simple.pm line 62
Devel::Declare::MethodInstaller::Simple::parser(Method::Signatures::Simple=HASH(0x8292a3fa8), "method", 1, 1) called at /u/ae/envs/plenv/versions/5.38.2/lib/perl5/site_perl/5.38.2/amd64-freebsd/Devel/Declare/MethodInstaller/Simple.pm line 25
Devel::Declare::MethodInstaller::Simple::__ANON__("method", 1) called at /u/ae/envs/plenv/versions/5.38.2/lib/perl5/site_perl/5.38.2/amd64-freebsd/Devel/Declare.pm line 277
Devel::Declare::linestr_callback("const", "method", 1) called at t line 10
两个问题:
use utf8
杂注会干扰Method::Signatures::Simple
的使用,以及Method::Signatures::Simple
与use utf8
一起使用?Devel::Declare
(已弃用)挂钩 Perl 解析器的方式造成的,这可能无法完全解释 UTF-8 源代码。use utf8;
时,解析器对源代码的布局和结构的期望可能会发生变化,可能会导致解析错误或与修改解析器行为的模块发生冲突。
确保您的源代码文件以 UTF-8 编码保存,不带 BOM(字节顺序标记)。
并且,如果可能,请考虑对方法签名使用可能与 UTF-8 源代码更兼容的不同模块。
MooseX::Method::Signatures
也已弃用,并包含该启发性评论:
警告:
和MooseX::Method::Signatures
基于MooseX::Declare
,这是一个最初由mst实现的巨大的破解包,其目的是通过它的存在来扰乱perl核心开发人员,以至于他们实现了正确的关键字核心处理。Devel::Declare
从 perl5 版本 14 开始,这个目标已经实现,并且诸如
、Devel::CallParser
和Function::Parameters
等模块提供了破坏 Perl 语法的机制,不需要致幻药物来解释它们产生的错误消息。Keyword::Simple
例如,将
Function::Parameters
与 UTF-8 一起使用:
use 5.034;
use warnings;
use utf8;
use Function::Parameters;
use Moose;
binmode(STDOUT, ':encoding(utf-8)');
package User {
use Moose;
use Function::Parameters;
has 'name' => (is => 'rw', isa => 'Str', default => sub { return 'foo' });
method xname() {
return "čč" . $self->name . "ňň";
}
}
my $u = User->new;
say $u->xname;