Raku 语法操作抛出“无法绑定 Nil 类型对象中的属性。您是否忘记了“.new”?使用“make”时出错
我在一个类中使用此方法,该方法抛出 Cannot Binding attribute in a Nil 类型对象。您是否忘记了“.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
方法注释掉该行,一切都会正常。
I have this method in a class that's throwing a 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);
}
As far as I can tell, this code matches what's in the official documentation. So not sure why I'm getting this error. I have no idea what attribute or Nil object the compiler is referring to. If I comment out the line with the make
method, everything works fine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
操作方法通常使用
$/
作为参数名称是有原因的:因为make
函数查找$/
> 以便将提供的对象与其关联。您可以使用$match
,但随后需要调用make
方法:提及
Nil
是因为操作方法中较早的匹配失败导致$/
被设置为Nil
。我猜您避免使用更惯用的
$/
作为操作方法的参数,因为它妨碍在操作方法中进行进一步匹配。在操作方法中进行进一步匹配意味着文本将被解析两次(一次在语法中,再次在操作中),这不是那么有效,通常最好避免(通过将解析工作移至语法中)。作为最后一个风格点,如果仅在方法中使用语法和操作类,则在方法中声明语法和操作类是一种巧妙的封装,但明智的做法是对它们进行范围化(
my
>我的语法 FindHeaders { ... }),否则它们最终将安装在最近的封闭包中。There's a reason that action methods typically use
$/
as the argument name: because themake
function looks for$/
in order to associate the provided object to it. You can use$match
, but then need to call themake
method on that instead:The mention of
Nil
is because the failed match earlier in the action method resulted in$/
being set toNil
.I guess you avoided the more idiomatic
$/
as the parameter of the action method because it gets in the way of doing further matching in the action method. Doing further matching in action methods means that the text is being parsed twice (once in the grammar and again the action), which is not so efficient, and usually best avoided (by moving the parsing work into the grammar).As a final style point, declaring grammars and action classes in a
method
is neat encapsulation if they are only used there, but it would be wise tomy
scope them (my grammar FindHeaders { ... }
), otherwise they shall end up installed in the nearest enclosing package anyway.错误 - 这里有点猜测,但看起来这个错误是在创建新对象期间生成的。它指向
my $tc = Lingua::EN::Titlecase.new($match)
行。我想知道您是否想将 Str 传递到此函数调用中,例如使用"$match"
或~$match
...Err - bit of a guess here but looks like this error is generated during creation of a new object. That points to the line
my $tc = Lingua::EN::Titlecase.new($match)
. I wonder if you want to pass a Str into this function call e.g. with"$match"
or~$match
...