2010-09-07 24 views
6

Wygląda na to, że niektóre (wiele?) Moduły w CPAN są częściowo implementowane w C przy użyciu XS i mogą w razie potrzeby powrócić do implementacji czystego perlera. Chociaż jest to inteligentne, może oczywiście zaszkodzić wydajności i chciałbym wiedzieć, że to się dzieje, więc mogę naprawić problem.Zatrzymanie modułów Perla XS z cichego powrotu do czystej perle

Czy istnieje ogólny sposób zatrzymania lub wykrycia tego typu awaryjnego?

Na przykład ten problem spojrzeć na (bardzo przydatna) Date::Simple (code snippet)

+1

Odpowiedź na ogólne podejście, ale jako "DateTime" jest defacto perl distro do reprezentowania dat. –

+1

@Evan Carroll, DateTime może być najpopularniejszym (i pełnometrażowym), ale nie jest to jedyny użytkownik, z którego korzystają. Istnieje wiele modułów daty Perla. – cjm

Odpowiedz

6

Każde rozwiązanie musiałoby być na każdego modułu podstawy (bo decyzja o których realizacja w użyciu jest przez sam moduł macierzysty, a nie jakiś mechanizm w Perlu). W przypadku, gdy cytujesz, sprawdzanie wartości $ Date :: Simple :: NoXs po instrukcji use powie ci, czy XS jest używany, czy nie.

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

Na przykład, aby wykryć, czy Scalar :: Util używa XS lub czystej wersji Perl trzeba sprawdzić istnienie funkcji dualvar.

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

W ten sposób 'Scalar :: Util' mówi o tym, czy XS nie załadował się, ale myślę, że lepiej byłoby z zewnątrz sprawdzić' @Scalar :: Util :: EXPORT_FAIL', który 'Scalar :: Util 'jawnie próbuje skonfigurować dla ciebie. –

+0

Prawdopodobnie lepiej byłoby "ostrzec" niż "umrzeć", ponieważ wersja czystego Perla powinna nadal działać; jest wolniej. – cjm

5

To naprawdę dobra funkcja. Niestety, w przeciwieństwie do tego, co zaprogramował autor modułu, perl nie ma wiedzy, czy moduł ma warianty XS lub Pure Perl (PP) i czy silnik został załadowany poprzez awarię.

Ten przykład, który wprowadzasz, jest potęgowany przez efekt, w którym są one pakowane w tej samej dystrybucji i module, i to wszystko odbywa się wewnętrznie. Zamontowałbym go zgodnie z konwencją CPAN: DateSimple, która wymaga DateSimple::PP i zaleca DateSimple::XS. W ten sposób robią to inni. Ta metoda pozwala bezpośrednio używać konstruktora ::XS do wymuszania użycia XS i jednocześnie nie instaluje nawet wariantu pureperl. Alternatywnie możesz je spakować razem - tak robi Template::Stash z Template::Stash::XS. Pierwszym krokiem do uzyskania czegoś ujednoliconego jest uzyskanie funkcji ad-hoc.

Takie rzeczy można łatwo zrobić, jeśli wszystkie moduły pociągnął w Moose::Role który dostarczył kilka podstawowych atrybutów _xs_class_name, _pp_class_name i engine_override. Ale znowu nie ma nic, co mogłoby zaowocować nawet zunifikowanym interfejsem API.

+0

+1 dla * :: XS * :: PP info .. nie rozwiązuje mojego problemu z atm. chociaż –

1

Istnieje ogólny sposób na wykrycie, że twoja funkcja to CV XSUB. Sprawdź tylko, czy slot XSUB w CV zwraca wskaźnik nie-NULL, czy nie.

np. sprawdź My :: func

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