Perl würde ein wenig Hilfe benötigen, dies zu tun. Weil Codenreferenzen, die in Hashes gespeichert sind, nicht als "Methoden" betrachtet werden. Methoden werden als Einträge in eine Package-Symboltabelle implementiert.Perl ist mehr Klasse-orientierte als JavaScript, die stolz verkündet, dass es mehr objektorientierte (auf einzelne Objekte) ist.
Um diese Funktionalität ausführen zu können, müssten Sie eine Klasse erstellen, die Referenzen auf diese Weise zuordnet. Der Weg, Methoden in der Symboltabelle zu umgehen, ist die AUTOLOAD
Methode. Wenn ein Paket eine AUTOLOAD
Unterroutine enthält, wird ein Aufruf an ein gesegnetes Objekt, das Perl in der Vererbungskette nicht finden kann, AUTOLOAD
aufrufen und die paketspezifische (our
) Variable setzen $AUTOLOAD
wird die volle Name der sein Funktion.
Wir erhalten den Namen der aufgerufenen Methode, indem wir den letzten Knoten (nach dem letzten '::') des voll qualifizierten Subnamens abrufen. Wir prüfen, ob dort eine Codeferenz vorhanden ist, und falls ja, können wir sie zurückgeben.
package AutoObject;
use strict;
use warnings;
use Carp;
use Params::Util qw<_CODE>;
our $AUTOLOAD;
sub AUTOLOAD {
my $method_name = substr($AUTOLOAD, index($AUTOLOAD, '::') + 2);
my ($self) = @_;
my $meth = _CODE($self->{$method_name});
unless ($meth) {
Carp::croak("object does not support method='$method_name'!");
}
goto &$meth;
}
1;
Dann würden Sie das Objekt in dieser Klasse segnen:
package main;
my $obj
= bless { foo => 1
, hello => sub { return 'world' }
}, 'AutoObject';
print $obj->hello();
Normalerweise in einem AUTOLOAD
Unter I "Zement" Verhalten. Das heißt, ich erstelle Einträge in die Paketsymboltabelle, um das nächste Mal AUTOLOAD
zu vermeiden. Aber das ist normalerweise für ein vernünftig definiertes Klassenverhalten.
Ich entwarf auch eine QuickClass
, die ein Paket für jedes deklarierte Objekt erstellt, aber das eine Menge von Symboltabellenkonflikten enthält, die jetzt Tage wahrscheinlich besser mit Class::MOP
erledigt werden.
den Vorschlag von Eric Strom gegeben, können Sie den folgenden Code in das AutoObject Paket hinzuzufügen. Der import
Sub würde jederzeit jemand heißen use
-d AutoObject
(mit dem Parameter 'object'
).
# Definition:
sub object ($) { return bless $_[0], __PACKAGE__; };
sub import { # gets called when Perl reads 'use AutoObject;'
shift; # my name
return unless $_[0] eq 'object'; # object is it's only export
use Symbol;
*{ Symbol::qualify_to_reference('object', scalar caller()) }
= \&object
;
}
Und dann, wenn Sie ein "Objektliteral" erstellen möchten, können Sie einfach tun:
use AutoObject qw<object>;
Und der Ausdruck wäre:
object { foo => 1, hello => sub { return 'world' } };
Man könnte sogar tun :
object { name => 'World'
, hello => sub { return "Hello, $_[0]->{name}"; }
}->hello()
;
Und Sie haben ein "Objekt wörtlicher "Ausdruck. Vielleicht würde das Modul besser Object::Literal
heißen.
Perl Methoden nicht Felder in einem Hash sind - das ist nicht Java. – Ether
JavaScript ist auch nicht Java. – cjm