2014-11-26 19 views
6
use java::util::zip::CRC32:from<java>; 

my $crc = CRC32.new(); 
for 'Hello, Java'.encode('utf-8') { 
    $crc.'method/update/(B)V'($_); 
} 
say $crc.getValue(); 

niestety, to nie działaJak wywołać metodę Java z perl6

Method 'method/update/(B)V' not found for invocant of class 'java.util.zip.CRC32' 

Kod ten jest dostępny pod następującymi linkami. Jest to jedyny przykład byłem w stanie znaleźć

  1. Rakudo Perl 6 on the JVM (slides)
  2. Perl 6 Advent Calendar: Day 03 – Rakudo Perl 6 on the JVM
+1

FWIW [niedawnej dyskusji java międzyoperacyjne na kanale IRC freenode # perl6] (http://irclog.perlgeek.de/perl6/2014-11-28#i_9733083). – raiph

+2

Fwiw, w tegorocznym kalendarzu adwentowym jest [W kierunku czystszego współdziałania JVM] (http://perl6advent.wordpress.com/2014/12/12/day-12-towards-cleaner-jvm-interoperability/). – raiph

Odpowiedz

6

odpowiedź końcowa

Łącząc czyszczenie kodu wyjaśnione w Twoja odpowiedź czyszczone sekcja poniżej ulepszeń Pepe Schwarza wymienionych w Oczekiwanie alert sekcja poniżej otrzymujemy:

use java::util::zip::CRC32:from<Java>; 

my $crc = CRC32.new(); 

for 'Hello, Java'.encode('utf-8').list { 
    $crc.update($_); 
} 

say $crc.getValue(); 

Twoja odpowiedź oczyścić

use v6; 
use java::util::zip::CRC32:from<Java>; 

my $crc = CRC32.new(); 

for 'Hello, Java'.encode('utf-8').list { # Appended `.list` 
    $crc.'method/update/(I)V'($_); 
} 
say $crc.getValue(); 

Jedna ważna zmienił nieco jest dołączany .list.

Fragment 'Hello, Java'.encode('utf-8') zwraca obiekt, utf8. Ten obiekt zwraca tylko jedną wartość (samą w sobie) do instrukcji for. Tak więc for iteruje tylko raz, przekazując obiekt do bloku kodu z linią .

Iteracja tylko raz mogłoby mieć sens, jeśli linia update był .'method/update/([B)V', który odwzorowuje się do metody Java, która oczekuje bufor 8 bitów wskazówki, które jest w zasadzie to, co Perl 6 utf8 jest.Jednak wymagałoby to pewnego wsparcia kodu Perl 6 (prawdopodobnie w rdzennym kompilatorze) do marszałkowania (automagicznie konwertować) Perla 6 utf8 do Javy buf[] i jeśli ten kod kiedykolwiek istniał/działał, to na pewno nie działa, gdy testuję z najnowsze Rakudo.

Ale jeśli dołącza się rozważny .list, jak pokazano powyżej i zmienia blok kodu, aby dopasować, rzeczy się sprawdzają.

Po pierwsze, .list powoduje, że instrukcja for iteruje po serii liczb całkowitych.

Po drugie, tak jak ty, nazwałem wersję Integer arg metody Java (.'method/update/(I)V') zamiast oryginalnej wersji argentyńskiej, a kod następnie działał poprawnie. (Oznacza to, że binarna reprezentacja niepodpisanych 8 bitowych liczb wrócił z obiektu Perl 6 utf8 jest albo już dokładnie jaki sposób Java oczekuje lub jest automagicznie marshaled dla ciebie.)

Innym wymagana zmiana jest taka, że ​​from<java> musi być from<Java> za komentarz poniżej - dzięki.

Oczekiwanie alert

Począwszy od stycznia 2015:

  • Jedynie używając backendu JVM dla Rakudo/NQP (tj z systemem czystego kodu P6 na JVM) nadal potrzebuje więcej twardnienie zanim zostanie oficjalnie zadeklarowany jako gotowy do użycia produkcyjnego. (Jest to dodatek do wszechstronnego hartowania, którego oczekuje się, że cały ekosystem P6 zostanie poddany w tym roku.) Mam nadzieję, że backend JVM pojawi się tam w 2015 r. - być może będzie to część początkowego oficjalnego uruchomienia Perla 6, gotowego na wykorzystanie produkcji w tym roku - ale to w dużej mierze zależy od popytu i jest więcej deweloperów, którzy go używają i dostarczają łatki.

  • Kodowanie kodu P6 kodu Java to dodatkowy projekt. W ostatnich kilku miesiącach Pepe Schwarz poczynił wielkie postępy w szybkim wchodzeniu na rynek, uczeniu się kodu i landing commits. Zaimplementował już oczywiście ładniejsze wywołania skrótów pokazane na początku tej odpowiedzi i uzupełnił o wiele więcej logiki łączącej typy P6 i Java i aktywnie zabiega o opinie i prośby o konkretne ulepszenia.

+0

Zgadywanie przez https://github.com/rakudo/rakudo/commit/db155f595408610bbd68a14846b3c7dcd1c0734d Powiedziałbym, że zaktualizowany kod interopu powinien brzmieć "... CRC32: od ;' (z kapitałem 'J'), nie? – user7610

+0

Dzięki. Naprawiony.(Obecny Rakudo uruchomił mój oryginalny kod bez ostrzeżenia o wycofaniu, ponieważ zatwierdzenie nie wycofuje go, dopóki wydanie nie zostanie oznaczone tagiem 2015.1 z powodu opóźnienia w tym miesiącu). – raiph

2

kod, który jest odpowiedzialny za ten obszar współdziałanie Java znajduje się w klasie org.perl6.nqp.runtime.BootJavaInterop. Sugeruje to, że przeciążone metody są identyfikowane przez ciąg method/<name>/<descriptor>. Deskryptor jest obliczany w funkcji org.objectweb.asm.Type#getMethodDescriptor. Ten słoik jest dostępny przez maven od http://mvnrepository.com/artifact/asm/asm.

import java.util.zip.CRC32 
import org.objectweb.asm.Type 

object MethodSignatures { 
    def printSignature(cls: Class[_], method: String, params: Class[_]): Unit = { 
    val m = cls.getMethod(method, params) 
    val d = Type.getMethodDescriptor(m) 
    println(m) 
    println(s"\t$d") 
    } 
    def main(args: Array[String]) { 
    val cls = classOf[CRC32] 

    # see https://docs.oracle.com/javase/8/docs/api/java/util/zip/CRC32.html 
    val ab = classOf[Array[Byte]] 
    val i = classOf[Int] 

    printSignature(cls, "update", ab) 
    printSignature(cls, "update", i) 
    } 
} 

Drukuje

public void java.util.zip.CRC32.update(byte[]) 
    ([B)V 
public void java.util.zip.CRC32.update(int) 
    (I)V 

Ponieważ chcę zadzwonić do aktualizacji (int) wariant tego przeciążone metody, metoda prawidłowe wezwanie (on line 5 programu przykład) jest

$crc.'method/update/(I)V'($_); 

ten wywala z

This representation can not unbox to a native int 

wreszcie, z jakiegoś powodu nie rozumiem, zmieniającym tę samą linię do

$crc.'method/update/(I)V'($_.Int); 

poprawek i przykład działa poprawnie.

Ostateczna wersja kodu jest

use v6; 
use java::util::zip::CRC32:from<java>; 

my $crc = CRC32.new(); 

for 'Hello, Java'.encode('utf-8') { 
    $crc.'method/update/(I)V'($_.Int); 
} 
say $crc.getValue(); 
+1

(Zobacz moją pełną odpowiedź na twoje pierwotne pytanie dla jakiegoś kontekstu do tego komentarza.) '.Int' w twojej odpowiedzi skutkuje przepuszczeniem długości' utf8', więc dostajesz crc dla liczby całkowitej '11'. Wydaje się działać, ale daje fałszywy wynik. – raiph

1

Dostałem to do pracy na Perl 6.c z następujących modyfikacji (Jan 4, 2018):

use v6; 
use java::util::zip::CRC32:from<JavaRuntime>; 

my $crc = CRC32.new(); 

for 'Hello, Java'.encode('utf-8').list { 
    $crc.update($_); 
} 
say $crc.getValue(); 

skutkuje:

% perl6-j --version 
This is Rakudo version 2017.12-79-g6f36b02 built on JVM 
implementing Perl 6.c. 

% perl6-j crcjava.p6 
1072431491 
Powiązane problemy