Suchen Sie nach Perl, um zu überprüfen, ob $ self eine Klasse oder ein Objekt ist.

In Perl wurde ich gerade von etwas gebissen, das wie der folgende Fehler aussah:

package Foo;
sub method {
    my $self = shift;
    my @args = @_;
    ...
}

wo ich es als Subroutine aufgerufen habe, nicht als Methode:

Foo::method( "arg1", "arg2" );

Anstatt es als Methode aufzurufen - in diesem Fall war es eine "Klassenmethode":

Foo->method( "arg1", "arg2" );

Calling Foo :: method ("arg1", "arg2") hat dazu geführt, dass "arg1" gelöscht wurde.

Ähnliche Überlegungen können bei einer "Objektmethode" auftreten:

my $object = Foo->new();
$obj->method( "arg1", "arg2" );

Gibt es eine freundliche, prägnante Perl-Sprache, mit der überprüft werden kann, ob das erste Argument, das üblicherweise als @ bezeichnet wir$self, ist tatsächlich ein Objekt in der Klasse (Paket) und / oder der Klassen- / Paketname?

Das Beste, was ich mir ausgedacht habe, ist:

package Foo;
sub method {
    my $self = ($_[0]->isa(__PACKAGE__) ? shift @_ : die "...error message...";
    my @args = @_;
    ...
}

Das ist nicht viel prägnanter als

package Foo;
sub method {
    my $self = shift;
    die "...error message..."  if $self->isa(__PACKAGE__);
    my @args = @_;
    ...
}

ode

package Foo;
use Carp::Assert;
sub method {
    my $self = shift;
    assert($self->isa(__PACKAGE__));
    my @args = @_;
    ...
}

Anmerkungen

Ich kenne mich mit Perl-Signaturen aus, verwende aber keine experimentellen Funktionen.

Ich weiss Bescheiduse attributes und:method. Ist das der beste Weg? Ähnliche Bedenken hinsichtlich "sich entwickelnder" Funktionen.

Ich weiß über Moose Bescheid - aber ich glaube nicht, dass Moose dies erzwingt. (Habe ich etwas vergessen.

Das Problem mit Perl ist, dass es so viele Möglichkeiten gibt, etwas zu tun.