【问题标题】:C++-like usage of Moose with Perl for OOP类似 C++ 的 Moose 与 Perl 的 OOP 用法
【发布时间】:2009-08-27 15:39:59
【问题描述】:

我一直在和 Moose 玩耍,感受一下。我想要一个纯虚函数的例子,比如 C++,但用 Moose 的说法(特别是 C++ 外观)。我知道,即使 Moose 采用比普通 Perl 更严格的模型,仍然有不止一种方法可以完成我的要求(通过方法修饰符或 SUPER:: 调用)。这就是为什么我特别要求尽可能地类似于 C++ 的实现。至于“为什么?”这个限制?主要是出于好奇,但也计划将一些 C++ 代码移植到带有 Moose 的 Perl,以一种以 C++ 为中心的人大部分可以认同的方式。

【问题讨论】:

  • 我将尝试从问题移至答案部分。
  • 哎呀,这个问题已经是使用 Moose 在 Perl 中搜索纯虚函数时的第三个响应。对于那些感兴趣的人,与此半相关的 perlmonks 讨论在这里:perlmonks.org/?node_id=742013。他们那边似乎也没有具体的答案。
  • 可能是因为除了 C++ 程序员之外的所有人都称它们为“方法”。

标签: c++ perl oop moose


【解决方案1】:

我可以考虑使用角色而不是子类化的这种方式:

{
    package AbstractRole;
    use Moose::Role;
    requires 'stuff';  
}

{
    package Real;
    use Moose;
    with 'AbstractRole';
}

这会产生编译错误,因为 Real 没有定义 stuff

stuff 方法添加到 Real 现在可以使其工作:

{
    package Real;
    use Moose;
    with 'AbstractRole';

    sub stuff { print "Using child function!\n" }
}

【讨论】:

  • 是的,如果我只想要一个界面,这就是它的实现方式。我通过研究和这里的讨论发现,我可能无法完全做我希望做的事情。
  • 我认为这可以让你大部分时间。如果您觉得进一步扩展此功能有好处,请在 irc.perl.org 上的 #moose 或邮件列表 moose@perl.org 与 Moose 家伙聊天。
  • @draegtun 是的,我认为这是我所希望的最好的近似值。感谢您的帮助!
【解决方案2】:

您可能还想看看 Jesse Luehrs 的 MooseX::ABC。 它似乎与这里的一些实现非常相似。摘自:

package Shape;
use Moose;
use MooseX::ABC;

requires 'draw';

package Circle;
use Moose;
extends 'Shape';

sub draw {
    # stuff
}

my $shape = Shape->new; # dies
my $circle = Circle->new; # succeeds

package Square;
use Moose;
extends 'Shape'; # dies, since draw is unimplemented

我知道 Jesse 白天是一名 C++ 程序员。

【讨论】:

  • 感谢您的提示,我一定会检查的!
  • 更新了从 0.20 版指向当前版本的链接。 0.30 版添加了子类抽象基类和更多抽象类。
【解决方案3】:

看来我不能完全用 Moose 做我想做的事,但我可以用 Roles 非常接近。以下是 Moose 手册 entry 的角色信息:

角色与抽象基类

如果你熟悉这个概念 其他抽象基类 语言,你可能会想使用 角色的方式相同。

您可以定义“仅接口” 角色,只包含一个列表 所需的方法。

但是,任何使用这个的类 角色必须执行所有 所需的方法,直接或 通过从父母那里继承。你 不能延迟方法要求 检查以便它们可以实施 按未来的子类。

因为角色定义了所需的 直接方法,添加基类 混合不会取得任何成果。 我们建议您简单地消费 每个类中的接口角色 实现该接口。

【讨论】:

  • 快!你的答案出现在我整理我的时候;-)
  • @draegtun 真有趣!您的回答真的很有帮助,特别是对于希望使用 Moose 实现接口的人。我刚刚提出了一个奇怪的问题,我通过进一步的研究发现它可能没有确定性的答案。我仍在尝试确定这是因为我在询问之前完全不了解该区域,还是 Moose 缺少此功能;)
  • 嗯。只是我还是那个帮助实际上不是很有帮助?它似乎在说'如果你想实现一个带有角色的抽象类,它就行不通,因为它们不是一回事;取而代之的是,看那边,一只会飞的猪!我仍然对(a)抽象类的层次结构如何(特别是 MooseX::ABC 是否被认为是好的)或(b)为什么 ABC 对 Moose 程序不利。
【解决方案4】:

这是我的尝试(没有角色,有关角色的信息请参阅其他答案):

package Abstract;
use Moose;

sub stuff;

package Real;
use Moose;
extends 'Abstract';

override 'stuff' => sub { print "Using child function!\n"; }

【讨论】:

  • 我不知道你在说什么,但似乎你希望 Abstract 是一个抽象基类,而 stuff 方法(不是函数)是纯虚拟的。只写sub stuff {} 就立即违反了这一点。所以,基类方法应该是sub stuff { croak }
  • @Sinan 我想要类似 C++ 的东西:virtual void stuff() = 0;
  • croak 来自 Carp,必须导入。将 'use Carp qw(croak);` 添加到您希望在其中使用它的任何包中。
  • @Kyle Walsh croak 是一个 hack,确保没有调用 Abstract->stuff 的代码似乎可以工作,而空的子正文不会阻止它。
  • Moose 会为您导入confess(),这样 s/croak/confess/ 就可以了。然而,正如 just 在 #moose sub stuff { 承认; 中指出的那样。 } 不做 compile 时间检查 ... Role 和 MX::ABC 解决方案做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 2014-05-23
  • 1970-01-01
  • 2012-08-11
  • 2011-07-09
相关资源
最近更新 更多