gpt4 book ai didi

Perl:当在方法中调用时,ref($self) 可以返回除 __PACKAGE__ 或 undef 之外的任何内容吗?

转载 作者:行者123 更新时间:2023-12-01 08:20:16 25 4
gpt4 key购买 nike

我在一个类中有一个方法,我需要确保它只在对象实例上调用,而不是作为类方法。

我可能会做这样的事情:

# Edit: this is terrible, don't do this, it breaks inheritance.
sub foo
{
my ($self) = @_;

if (ref($self) ne __PACKAGE__) { return; }

...do stuff
}

但我认为这样做会更有效率:
sub foo
{
my ($self) = @_;

if (not ref($self)) { return; }

...do stuff
}

问题:
  • 假设如果 ref() 返回不是 undef 它将返回当前包是否安全?
  • 理想情况下,我想在我所有的健全性检查方法中回顾并做类似的事情。这是个坏主意吗?
  • 有没有更糟糕的方式来做我想做的事?

  • 在这种情况下,“使用驼鹿”不是可接受的答案。但是,如果您不得不这么说,请告诉我 moose 如何使这变得简单或更高效。我可能想将它合并到我自己的对象系统中。

    谢谢!

    已编辑 反射(reflect) ref 从不返回 undef,只返回一个空字符串。

    编辑 2 这是一个后续问题。下面有人建议使用:
    $self->isa(__PACKAGE__)

    但这不会总是成功吗?当然,除非调用者做了一些非常愚蠢的事情,比如:
    MyClass::MyMethod($ref_to_some_other_object)

    最佳答案

    首先,您可能应该 croak而不是默默地什么都不做,因为根据您的规范,调用 foo作为类方法是违约行为。

    其次,仅检查第一个参数是否为引用就足够了。如果涉及继承,您的方法将失败:

    #!/usr/bin/perl

    package A;
    use Carp;

    sub new { bless {} => shift }
    sub foo {
    croak "I am not in " . __PACKAGE__ unless __PACKAGE__ eq ref(shift)
    }

    package B;

    use base 'A';

    package main;

    $x = B->new;

    $x->foo;
    C:\Temp> tI am not in A at C:\Temp\t.pl line 19

    See also perldoc -f ref:

    If the referenced object has been blessed into a package, then that package name is returned instead. You can think of ref as a typeof operator.

    So:

    sub foo {
    croak "Don't call as class method" unless ref shift;
    }

    最后,请注意 ref 从不返回 undef .

    将此检查添加到每个方法中是否是个好主意?我想人们可以从契约(Contract)设计的角度提出这个论点。

    另一方面,我的方法假定它们被称为实例方法,并且我只检查方法被称为类方法的可能性,如果该方法在这样调用时可以提供有意义的替代行为。

    我也不记得任何有这些检查的模块。

    顺便说一句,而不是
    sub foo {
    my ($self) = @_;

    你应该使用
    sub foo {
    my $self = shift;

    @_ 中只保留方法的参数被拆包。或者,您应该一举解开所有论点:
    sub foo {
    my ($self, $bar, $baz) = @_;

    关于Perl:当在方法中调用时,ref($self) 可以返回除 __PACKAGE__ 或 undef 之外的任何内容吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1649181/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com