perl - 为什么在使用 Moose 时覆盖 new 是 "very bad practice"?

标签 perl constructor overriding inline moose

来自 Moose::Manual::BestPractices页:

Overriding new is a very bad practice. Instead, you should use a BUILD or BUILDARGS methods to do the same thing. When you override new, Moose can no longer inline a constructor when your class is immutabilized.



我的问题是为什么这被认为是非常糟糕的做法?

我认为“内联”构造函数只是意味着构造函数与类定义在同一个包中。如果这是真的,是否意味着如果您覆盖了 new在该包中,构造函数仍将被视为“内联”构造函数?如果我错了,请纠正我。我不完全理解构造函数“内联”意味着什么的概念。

我遇到这个问题的原因是因为我正在创建一个构建对象列表的脚本。如果用户尝试创建与列表中的对象相同的新对象,我想停止 Moose从创建一个新对象并返回对现有对象的引用。

创建新对象时,我想将其推送到列表中并返回新对象。当尝试创建现有对象时,应返回现有对象而不是将其推送到列表中。
# Some pseudo code showing the logic of what I attempted
around BUILDARGS => sub {
    my ($orig, $self, %args) = @_;

    # loop through objects in list
    for my $object (@list) {

        # if $args used to define the new object
        # match the arguments of any object in the list
        # return the matched object

        # I want this to directly return the object
        # and skip the call to BUILD
    }

    return $self->orig(
        # Insert args here
    );
};

sub BUILD {
    my ($self) = @_;

    # I don't want this call to happen if the object already existed
    push @list, $self;
}   

创建新对象时,我尝试使用 BUILD创建后将其推送到列表中。问题是当我尝试创建现有对象并使用 BUILDARGS 时返回现有对象似乎并没有停止 Moose来自调用 BUILD它试图将对象推送到列表中。

我能够解决这个问题的唯一方法是覆盖 new并让它返回现有对象而不创建新对象。
# Some pseudo code showing the overridden constructor
sub new {
    my ($class, %args) = @_;

    # loop through objects in list
    for my $object (@list) {

        # if $args used to define the new object
        # match the arguments of any object in the list
        # return the matched object
    }

    # Build the object
    my $self = bless {
        # Insert args here
    }, $class;

    # Add the object to the list
    push @list, $object;
}

覆盖 new工作,但如果它真的是一个可怕的想法,如 Moose文档似乎表明,有没有更好的方法来做到这一点?

最佳答案

内联子例程意味着在调用点复制其代码,而不是插入子例程调用。这要快得多,因为它避免了在堆栈上收集参数和任何局部变量以及调用和返回操作的开销。如果类没有被声明为不可变的,这是不可能的,因为任何突变都可能意味着构造函数必须改变,因此不能再内联插入

关于perl - 为什么在使用 Moose 时覆盖 new 是 "very bad practice"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31076321/

相关文章:

Java继承和重写方法——修饰符的影响

flash - AS3 类/基类构造函数

perl - 使用 Perl 和 Net::OAuth2 将 POST 事件传输到 Google 日历

mysql - DBD::MySQL:如何使 "LongReadLen"正常运行?

perl - 无需正则表达式的简单搜索和替换

java - 具有默认参数值的构造函数

c# - 调用 COM 类的非默认构造函数

C++ 被此代码与多态性、指针和对象切片混淆

c# - 如何通过使用接口(interface)或抽象来确保类具有静态属性?

bash - 3 制表符分隔文件中的文件字符串匹配模式 awk