10
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();

残念ながら、これは機能しません

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

このコードは、次のリンクから入手できます。それは私が見つけることができた唯一の例です

  1. JVM 上の Rakudo Perl 6 (スライド)
  2. Perl 6 アドベント カレンダー: 3 日目 – JVM 上の Rakudo Perl 6
4

3 に答える 3

9

最終的な答え

以下の「Your answer cleanup up 」セクションで説明されているコードのクリーンアップと、以下の「 Expectation alert」セクションで言及されている Pepe Schwarz の改善を組み合わせると、次のようになります。

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

my $crc = CRC32.new();

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

say $crc.getValue();

あなたの答えはきれいになりました

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();

重要な変更点の 1 つは、追加され.listた .

そのため、 は1 回だけ反復し、その行を含むコード ブロックにオブジェクトを渡します。'Hello, Java'.encode('utf-8')utf8forforupdate

However, that would require some support Perl 6 code (presumably in the core compiler) to marshal (automagically convert) the Perl 6 into a Java and if that code ever existed/worked it sure isn't working when I test with the latest Rakudo .update.'method/update/([B)V'utf8utf8buf[]

しかし、上に示したように賢明なものを追加し、それ.listに合わせてコード ブロックを変更すると、うまくいきます。

まず、一連の整数を反復処理するステートメントになります.listfor

次に、あなたと同じように、元のバッファ引数バージョンの代わりに Java メソッドの整数引数バージョン ( .'method/update/(I)V') を呼び出したところ、コードは正しく機能しました。(これは、Perl 6 オブジェクトから返された符号なし 8 ビット整数のバイナリ表現がutf8、Java メソッドが期待するものとまったく同じであるか、自動的にマーシャリングされることを意味します。)

Another required change is that the from<java> needs to be from<Java> per your comment below -- thanks.

期待アラート

2015 年 1 月現在:

  • Rakudo/NQP に JVM バックエンドを使用する (つまり、JVM で純粋な P6 コードを実行する) だけでは、正式に本番環境で使用できると宣言する前に、さらに強化する必要があります。(これは、P6 エコシステム全体が今年受けることが予想される全面的な強化に加えてのことです。) JVM バックエンドは 2015 年に実現することが期待されます。今年は本番環境での使用が必要ですが、それは需要と、それを使用してパッチを提供する開発者が増えることに大きく依存します.

  • Java コードを呼び出す P6 コードは、追加のプロジェクトです。Pepe Schwarz は、この 2 か月間で速度を上げ、コードベースを学習し、コミットを開始することで大きな進歩を遂げました。彼は、この回答の冒頭に示されている明らかに優れた短縮名の呼び出しを既に実装しており、P6 と Java の型を変換するためのマーシャリング ロジックをさらに多く完成させており、フィードバックや特定の改善の要求を積極的に求めています。

于 2015-01-12T05:45:34.233 に答える
3

Java 相互運用のこの領域を担当するコードは、クラスにありorg.perl6.nqp.runtime.BootJavaInteropます。オーバーロードされたメソッドが文字列で識別されることを示唆していますmethod/<name>/<descriptor>。記述子は function で計算されますorg.objectweb.asm.Type#getMethodDescriptor。その jar は、http://mvnrepository.com/artifact/asm/asm から Maven を介して入手できます

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)
  }
}

これは印刷します

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

このオーバーロードされたメソッドの update(int) バリアントを呼び出したいので、正しいメソッド呼び出し (サンプル プログラムの 5 行目) は次のとおりです。

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

これはでクラッシュします

This representation can not unbox to a native int

最後に、何らかの理由で理解できず、同じ行を次のように変更します

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

それを修正すると、例は正常に実行されます。

コードの最終バージョンは

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();
于 2014-11-26T18:23:07.727 に答える