Perl requeriría un poco de ayuda para hacer esto. Porque no considera las referencias de código almacenadas en hashes como "métodos". Los métodos se implementan como entradas en una tabla de símbolos de paquete.Perl es más orientado a clases que JavaScript, que orgullosamente proclama que es más orientado a objetos (en objetos individuales).
Para poder hacer esa funcionalidad, debería crear una clase que asigne referencias de esta manera. La forma de evitar los métodos en la tabla de símbolos es el método AUTOLOAD
. Si un paquete contiene una subrutina AUTOLOAD
, cuando se realiza una llamada a un objeto bendito que Perl no ha podido encontrar en la cadena de herencia, se llamará AUTOLOAD
y configurar el paquete de ámbito (our
) Variable $AUTOLOAD
contendrá el completa nombre de la función.
Obtenemos el nombre del método llamado, obteniendo el último nodo (después del último '::') del nombre secundario completo. Miramos para ver si hay un coderef en esa ubicación, y si existe, podemos devolverlo.
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;
allí tendría que bendecir el objeto en esa clase:
package main;
my $obj
= bless { foo => 1
, hello => sub { return 'world' }
}, 'AutoObject';
print $obj->hello();
Normalmente, el comportamiento "cemento" en un sub AUTOLOAD
. Es decir, creo entradas en la tabla de símbolos del paquete para evitar AUTOLOAD
la próxima vez. Pero eso es generalmente para un comportamiento de clase razonablemente definido.
También diseñé un QuickClass
que crea un paquete para cada objeto declarado, pero que contiene una gran cantidad de disputas de tablas de símbolos que ahora probablemente se hagan mejor con Class::MOP
.
Dada la sugerencia de Eric Strom, podría agregar el siguiente código en el paquete AutoObject. El sub import
se llamaría en cualquier momento alguien use
-d AutoObject
(con el parámetro '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
;
}
Y luego, cuando se quería crear un "objeto literal", sólo podía hacer:
use AutoObject qw<object>;
Y la expresión sería:
object { foo => 1, hello => sub { return 'world' } };
Incluso se puede hacer :
object { name => 'World'
, hello => sub { return "Hello, $_[0]->{name}"; }
}->hello()
;
Y usted tiene un "objeto expresión literal ". Tal vez el módulo sea mejor llamado Object::Literal
.
métodos Perl no son campos en un hash - esto no es Java. – Ether
JavaScript tampoco es Java. – cjm