使用 "make" 时 Raku 语法操作抛出 "Cannot bind attributes in a Nil type object. Did you forget a '.new'?" 错误
Raku grammar action throwing "Cannot bind attributes in a Nil type object. Did you forget a '.new'?" error when using "make"
我在 class 中有这个方法,它会抛出 Cannot bind attributes in a Nil type object. Did you forget a '.new'?
method parse() {
grammar FindHeaders {
token TOP { [<not-header> | <header>]+ $ }
token not-header { ^^ <![#]> \N* \n }
token header { ^^ '#'{ 1 .. 6 } <content> \n }
token content { \N+ }
}
class HeaderActions {
method content($match) {
return if $match ~~ m/^^\#\s+<[A..Z]>+e*s/ || $match !~~ m/<[a..z]>/;
return if $match ~~ m/\|/ && ( $match ~~ m:i/project/ || $match ~~ m:i/\+\w/ );
my $tc = Lingua::EN::Titlecase.new($match);
my $new_title = $tc.title;
make($new_title);
}
}
my $t = $!content;
FindHeaders.parse($t, actions => HeaderActions.new);
}
据我所知,此代码与官方文档中的内容相符。所以不确定为什么会出现此错误。我不知道编译器指的是什么属性或 Nil 对象。如果我用 make
方法注释掉该行,一切正常。
错误 - 这里有点猜测,但看起来这个错误是在创建新对象期间生成的。那指向行 my $tc = Lingua::EN::Titlecase.new($match)
。我想知道你是否想将 Str 传递到这个函数调用中,例如"$match"
或 ~$match
...
method content($match) {
操作方法通常使用 $/
作为参数名称是有原因的:因为 make
函数查找 $/
以便将提供的对象与其关联。您 可以 使用 $match
,但之后需要调用 make
方法:
$match.make($new_title);
提到Nil
是因为action方法中较早的匹配失败导致$/
被设置为Nil
。
我猜你避免了更惯用的 $/
作为 action 方法的参数,因为它妨碍了在 action 方法中进行进一步匹配。在动作方法中做进一步匹配意味着文本被解析两次(一次在语法中,一次在动作中),效率不高,通常最好避免(通过将解析工作移动到语法中)。
作为最后的风格要点,在 method
中声明语法和动作 类 如果它们仅在那里使用,则它们是简洁的封装,但明智的做法是 my
限定它们的范围(my grammar FindHeaders { ... }
),否则它们最终将安装在最近的封闭包中。
我在 class 中有这个方法,它会抛出 Cannot bind attributes in a Nil type object. Did you forget a '.new'?
method parse() {
grammar FindHeaders {
token TOP { [<not-header> | <header>]+ $ }
token not-header { ^^ <![#]> \N* \n }
token header { ^^ '#'{ 1 .. 6 } <content> \n }
token content { \N+ }
}
class HeaderActions {
method content($match) {
return if $match ~~ m/^^\#\s+<[A..Z]>+e*s/ || $match !~~ m/<[a..z]>/;
return if $match ~~ m/\|/ && ( $match ~~ m:i/project/ || $match ~~ m:i/\+\w/ );
my $tc = Lingua::EN::Titlecase.new($match);
my $new_title = $tc.title;
make($new_title);
}
}
my $t = $!content;
FindHeaders.parse($t, actions => HeaderActions.new);
}
据我所知,此代码与官方文档中的内容相符。所以不确定为什么会出现此错误。我不知道编译器指的是什么属性或 Nil 对象。如果我用 make
方法注释掉该行,一切正常。
错误 - 这里有点猜测,但看起来这个错误是在创建新对象期间生成的。那指向行 my $tc = Lingua::EN::Titlecase.new($match)
。我想知道你是否想将 Str 传递到这个函数调用中,例如"$match"
或 ~$match
...
method content($match) {
操作方法通常使用 $/
作为参数名称是有原因的:因为 make
函数查找 $/
以便将提供的对象与其关联。您 可以 使用 $match
,但之后需要调用 make
方法:
$match.make($new_title);
提到Nil
是因为action方法中较早的匹配失败导致$/
被设置为Nil
。
我猜你避免了更惯用的 $/
作为 action 方法的参数,因为它妨碍了在 action 方法中进行进一步匹配。在动作方法中做进一步匹配意味着文本被解析两次(一次在语法中,一次在动作中),效率不高,通常最好避免(通过将解析工作移动到语法中)。
作为最后的风格要点,在 method
中声明语法和动作 类 如果它们仅在那里使用,则它们是简洁的封装,但明智的做法是 my
限定它们的范围(my grammar FindHeaders { ... }
),否则它们最终将安装在最近的封闭包中。