2010-09-07 18 views
6

Parece que algunos (¿muchos?) Módulos en CPAN se implementan parcialmente en C usando XS, y pueden recurrir a una implementación pura-perl si es necesario. Si bien esto es inteligente, obviamente puede perjudicar el rendimiento, y me gustaría saber que sucede para que pueda solucionar el problema.Detener los módulos Perl XS cayendo silenciosamente a pure-perl

¿Hay una manera general de detener o detectar este tipo de retroceso?

Para un ejemplo de este comportamiento echar un vistazo a la (muy práctico) Date::Simple (code snippet)

+1

He respondido en el enfoque genérico, pero como un aparte 'DateTime' es la distribución perl defacto para representar las fechas. –

+1

@Evan Carroll, DateTime puede ser el más popular (y completo), pero no es el único que usan las personas. Hay muchos módulos de fecha de Perl. – cjm

Respuesta

6

Cualquier solución tendría que ser en función de cada módulo (debido a que la decisión sobre qué aplicación a utilizar se realiza por el módulo padre en sí mismo, no algún mecanismo en Perl). En el caso que citó, verificando el valor de $ Date :: Simple :: NoXs después de la declaración de uso le dirá si XS se está utilizando o no.

use Date::Simple; 
die "not using XS for Date::Simple\n" if $Date::Simple::NoXs; 

Por ejemplo, para detectar si Scalar :: Util está utilizando la versión de Perl puros XS o usted tiene que comprobar la existencia de la función dualvar.

use Scalar::Util; 
die "not using XS for Scalar::Util\n" unless if @Scalar::Util::EXPORTFAIL; 
+0

Bueno, así es como 'Scalar :: Util' va diciendo si el XS no se pudo cargar, pero creo que sería mejor que fuera de la cuenta de verificación' @Scalar :: Util :: EXPORT_FAIL', que 'Scalar :: Util 'explícitamente intenta configurarlo para usted. –

+0

Probablemente sería mejor 'advertir' que 'morir', ya que la versión pura de Perl debería funcionar; es solo mas lento – cjm

5

Esta es una muy buena solicitud de funciones. Desafortunadamente, a menos de lo que el autor del módulo ha programado, Perl no tiene conocimiento si el módulo tiene variantes XS o Pure Perl (PP) y si el motor se cargó a través de la recuperación.

Este ejemplo que aparece se complica por el efecto de que están empaquetados en la misma distribución y módulo, y todo se hace internamente. Lo parchearía para seguir la convención CPAN: DateSimple, que requiere DateSimple::PP y recomienda DateSimple::XS. Así es como Text::CSV y otros lo hacen. Este método permite usar el constructor ::XS directamente para forzar el uso de XS y al mismo tiempo ni siquiera instalar la variante pureperl. Alternativamente, puede empaquetarlos juntos: esto es lo que Template::Stash hace con Template::Stash::XS. El primer paso para obtener algo unificado es obtener la funcionalidad ad-hoc.

Este tipo de cosas se puede hacer fácilmente si todos los módulos sacaron en una Moose::Role que proporciona algunos atributos básicos _xs_class_name, _pp_class_name y engine_override. Pero, de nuevo, no hay nada a partir de ahora que incluso siembra una API unificada para lograr esto.

+0

+1 para la información * :: XS * :: PP .. no resuelve mi problema atm. aunque –

1

Hay una manera general de detectar que su función es un CV XSUB. Solo comprueba si la ranura XSUB del CV devuelve un puntero no nulo o no.

p. Ej. verificar por My :: func

sub isxsub { 
    use B; 
    my $name = shift; 
    my $cv = B::svref_2object(\&$name); 
    return !!$cv->XSUB; 
} 
Cuestiones relacionadas