如何制作一个继承与 IO::Path 相同方法的 class?
How to make a class that inherits the same methods as IO::Path?
我想在 Raku 建立一个 class。这是我目前所拥有的:
unit class Vimwiki::File;
has Str:D $.path is required where *.IO.e;
method size {
return $.file.IO.s;
}
我想通过简单地让我的 class 继承 IO::Path 的方法来摆脱 size
方法,但我有点不知所措来完成这个。当我尝试创建新对象时,尝试 is IO::Path
会抛出错误:
$vwf = Vimwiki::File.new(path => 't/test_file.md');
Must specify a non-empty string as a path
in block <unit> at t/01-basic.rakutest line 24
Must specify a non-empty string as a path
我总是在看别人的代码时尝试别人的代码。你的没用。 (没有 $vwf
的声明。)这立即提醒我有人没有应用 Minimal Reproducible Example 原则。
所以我做到了,不到 60 秒后:
IO::Path.new
产生同样的错误。
为什么?
doc for IO::Path.new
显示其签名:
multi method new(Str:D $path, ...
因此,IO::Path
的 new
方法需要 位置 参数,即 Str
。你(和我的 MRE)还没有传递一个 Str
的位置参数。因此错误消息。
当然,您已经声明了自己的 属性 $path
,并传递了一个 named 参数来设置它,不幸的是,由于与名称 path
的巧合,这让您感到困惑,但这就是编程的乐趣。
下一步,拿 #1
我认为具有重复 IO::Path
的路径属性可能会导致不必要的复杂性 and/or 错误。所以我想我会拒绝它。
如果您要做的只是对文件名进行额外的检查,那么您可以这样写:
unit class Vimwiki::File is IO::Path;
method new ($path, |) { $path.IO.e ?? (callsame) !! die 'nope' }
callsame
重新分配 正在进行的例程调用(new
方法调用),使用完全相同的参数,到下一个最合适的候选人) 如果你的新的包含 callsame
没有被调用的话,它会被选择。在这种情况下,下一个候选者将是 IO::Path
.
的现有 new
方法
这似乎很好开始。然后你可以添加你认为合适的其他属性和方法...
下一步,走#2
...除了the IO::Path
bug you filed,这意味着你不能用正常的方式初始化属性,因为IO::Path
破坏了标准的对象构造协议! :(
Liz 展示了一种解决此错误的方法。
在这个答案的早期版本中,我不仅展示而且推荐了另一种方法,即通过 handles
委托而不是普通继承。从那以后我得出结论,那是 over-complicating 的事情,因此从这个答案中删除了它。然后我读了你的问题!
所以我猜委派方法可能仍然是合适的作为错误的解决方法。因此,如果稍后 reader 想看到它的实际效果,请按照 @sdondley 的 link 了解他们的代码。但我把它从这个答案的这个(希望是最终的!著名的遗言......)版本中删除,希望当你(后来 reader)阅读这个时,你只需要做一些真正的事情简单如 take #1.
我想在 Raku 建立一个 class。这是我目前所拥有的:
unit class Vimwiki::File;
has Str:D $.path is required where *.IO.e;
method size {
return $.file.IO.s;
}
我想通过简单地让我的 class 继承 IO::Path 的方法来摆脱 size
方法,但我有点不知所措来完成这个。当我尝试创建新对象时,尝试 is IO::Path
会抛出错误:
$vwf = Vimwiki::File.new(path => 't/test_file.md');
Must specify a non-empty string as a path
in block <unit> at t/01-basic.rakutest line 24
Must specify a non-empty string as a path
我总是在看别人的代码时尝试别人的代码。你的没用。 (没有 $vwf
的声明。)这立即提醒我有人没有应用 Minimal Reproducible Example 原则。
所以我做到了,不到 60 秒后:
IO::Path.new
产生同样的错误。
为什么?
doc for IO::Path.new
显示其签名:
multi method new(Str:D $path, ...
因此,IO::Path
的 new
方法需要 位置 参数,即 Str
。你(和我的 MRE)还没有传递一个 Str
的位置参数。因此错误消息。
当然,您已经声明了自己的 属性 $path
,并传递了一个 named 参数来设置它,不幸的是,由于与名称 path
的巧合,这让您感到困惑,但这就是编程的乐趣。
下一步,拿 #1
我认为具有重复 IO::Path
的路径属性可能会导致不必要的复杂性 and/or 错误。所以我想我会拒绝它。
如果您要做的只是对文件名进行额外的检查,那么您可以这样写:
unit class Vimwiki::File is IO::Path;
method new ($path, |) { $path.IO.e ?? (callsame) !! die 'nope' }
callsame
重新分配 正在进行的例程调用(new
方法调用),使用完全相同的参数,到下一个最合适的候选人) 如果你的新的包含 callsame
没有被调用的话,它会被选择。在这种情况下,下一个候选者将是 IO::Path
.
new
方法
这似乎很好开始。然后你可以添加你认为合适的其他属性和方法...
下一步,走#2
...除了the IO::Path
bug you filed,这意味着你不能用正常的方式初始化属性,因为IO::Path
破坏了标准的对象构造协议! :(
Liz 展示了一种解决此错误的方法。
在这个答案的早期版本中,我不仅展示而且推荐了另一种方法,即通过 handles
委托而不是普通继承。从那以后我得出结论,那是 over-complicating 的事情,因此从这个答案中删除了它。然后我读了你的问题!
所以我猜委派方法可能仍然是合适的作为错误的解决方法。因此,如果稍后 reader 想看到它的实际效果,请按照 @sdondley 的 link 了解他们的代码。但我把它从这个答案的这个(希望是最终的!著名的遗言......)版本中删除,希望当你(后来 reader)阅读这个时,你只需要做一些真正的事情简单如 take #1.