将角色混入可调用对象:Raku函数混入角色的报错排查
给Raku函数混入角色并调用自身的正确方式
你遇到的问题其实是因为在角色方法中调用self.CALL-ME的方式不对,不过别担心,这个操作完全是可行的,只需要调整一下调用方式就行。
错误原因分析
当你给&random-f混入Argable角色后,在argh方法里的self指代的是混合了角色的Callable对象。但CALL-ME作为Callable的方法,如果你用self.CALL-ME("argh")这种方法调用的形式,Raku会自动把self作为第一个参数传递给CALL-ME——而你的原始函数只期望1个参数,这就导致参数不匹配(你看到的错误信息行号可能有点误导,但本质是参数传递的问题)。
另外,直接去掉self.写CALL-ME("argh")会报错,是因为CALL-ME需要绑定到具体的Callable对象上调用,单独写它的话,Raku不知道要调用哪个对象的CALL-ME方法。
解决方法
其实在Raku中,任何Callable对象都可以直接用()来调用,这会自动触发它的CALL-ME方法,而且不需要处理方法调用时的self参数问题。你只需要把角色里的self.CALL-ME( "argh" )改成self("argh")就行:
my &random-f = -> $arg { "Just $arg" }; say random-f("boo"); # 输出: Just boo role Argable { method argh() { self("argh"); # 直接把self当作Callable调用 } } &random-f does Argable; say random-f.argh; # 输出: Just argh
这样运行就完全正常了,既实现了给函数混入角色的需求,也能正确调用原始函数的逻辑。
补充说明
Raku确实支持给Callable对象混入角色,因为Callable本身也是对象的一种,does关键字就是用来给对象动态混入角色的——你一开始的思路是完全正确的,只是调用方式需要调整。
内容的提问来源于stack exchange,提问作者jjmerelo
相关产品推荐
相关产品推荐

