如何通过trait为Block类型变量添加phaser实现调用权限校验?
问题原因说明
你遇到的报错是当前Rakudo编译器尚未实现对&前缀变量使用is trait的语法支持,你不需要通过is Block的方式声明变量类型,直接使用类型约束语法即可指定&变量的类型为Block。
可行实现方案
方案1:直接在Block内部定义phaser(最简洁)
Block内部的ENTER等phaser会在Block执行时自动触发,不需要额外调用add_phaser方法,示例代码:
my &doing-good = { ENTER { if Backtrace.new.grep: { .subname ~~ /bad/ } { fail("Not authorized to call this"); } } # 此处写入Block的原有执行逻辑 }
方案2:显式声明Block类型后调用add_phaser
如果你需要动态给已有的Block添加phaser,可以先声明Block类型的&变量,再调用add_phaser方法:
# 直接通过前缀类型约束声明变量为Block类型 my Block &doing-good = { # Block原有执行逻辑 }; # 动态添加ENTER phaser &doing-good.add_phaser: "ENTER", { if Backtrace.new.grep: { .subname ~~ /bad/ } { fail("Not authorized to call this"); } };
方案3:给Callable类型变量扩展功能
如果你确实需要使用Callable类型的变量,不需要用add_method方法,直接通过but运算符混合角色即可添加自定义方法或属性:
# 定义需要混入的角色 role PhaserSupport { method add-custom-phaser($type, &phaser) { self.add_phaser: $type, &phaser; } } # 声明Callable类型变量,混入自定义角色 my Callable &doing-good = sub { # 原有逻辑 } but PhaserSupport; # 调用混入的方法添加phaser &doing-good.add-custom-phaser("ENTER", { if Backtrace.new.grep: { .subname ~~ /bad/ } { fail("Not authorized to call this"); } });
内容的提问来源于stack exchange,提问作者jjmerelo
相关产品推荐
相关产品推荐

