8

Windowsでのパッケージ名に問題があるためaux、ライブラリのパッケージ階層内のヘルパー クラスを から移動しています。

de.sciss.scalainterpreter.aux

de.sciss.scalainterpreter

クラスはライブラリに対してプライベートprivate[scalainterpreter] object Helperです。

Typesafe Migration-Managerを使用すると、明らかに、変更に互換性がないことが報告されます。

Found 2 binary incompatibiities
===============================
 * class de.sciss.scalainterpreter.aux.Helper does not have a correspondent
   in new version
 * object de.sciss.scalainterpreter.aux.Helper does not have a correspondent
   in new version

しかし、クライアント コードがどちらのオブジェクトも呼び出さない場合でも、インターフェイスには互換性があるのではないかと思います。そのため、マイナー バージョンの増加を使用して変更を示し、これら 2 つのバージョンを同じ意味で使用できるようにすることができます。

正しい?

4

3 に答える 3

3

You are not specifying if Helper was already package private before the move. So I'll treat both cases:

  • If it was already package private:

    I suspect that the migration manager reports an incompatibility only because it must stay conservative: packages are open in scala (like in java), which means that client code might very well define a class package scalainterpreter. So by moving Helper, you would indeed break that class.

    However let's be pragmatic: de.sciss.scalainterpreter.aux is your package (and so should be their sub-packages), and nobody should define their own classes there. With this additional prerequiste, moving Helper is indeed a binary compatible change toward client scala code.

    As for client java code, it's a bit different because even if Helper is package private, its visibility is still public as far as the JVM is concerned, and thus the java compiler will happily let client code access Helper (thus client java code might very well already access Helper, despite it being declared package private).

  • If it was not package private before the move:

    Well, tough luck. Client code could very well already access Helper, and the move will certainly break that. As a side note, you can employ a little trick to make the change source-compatible, but alas not binary-compatible. Just add the following file:

    package de.sciss
    
    package object scalainterpreter {
      object aux {
        val Helper = _root_.de.sciss.scalainterpreter.Helper
      }
    }
    

With the above, you can still access Helper as de.sciss.scalainterpreter.aux.Helper, and it still compiles under windows (unlike defining a package aux, which does not compile because of the reserved meaning as a file name). But again, this is not binary compatible, only source compatible.

于 2012-09-06T15:30:40.423 に答える
1

インライン化されたコードは基本的にクライアント インターフェイスに流れ込んでいるため、インライン化によってクライアント コードが壊れる可能性があることは容易に理解できます。この例では、実際にリンケージ エラーを要求しています。javap | のようなことを実験して行うことができます。grep ヘルパーですが、あるレベルでは scalac に仕事を任せる必要があります。

package lib {

  object Lib {
    //import util.Helper
    @inline def result = Helper.help
  }

  //package util {

  private [lib] object Helper {
    @inline def help = "Does this help?"
  }
//}
}

無邪気に傍観しているクライアントのサンプル:

package client

object Test {
  import lib.Lib
  def main(args: Array[String]) {
    println(Lib.result)
  }
}

package-private クラスのパッケージの変更:

$ scala -cp "classes;target" client.Test
Does this help?

apm@halyard ~/tmp/taking-it-private
$ vi lib.scala

apm@halyard ~/tmp/taking-it-private
$ rm -rf classes/*

apm@halyard ~/tmp/taking-it-private
$ smalac -d classes -optimise lib.scala 

apm@halyard ~/tmp/taking-it-private
$ smala -cp "classes;target" client.Test
java.lang.ClassNotFoundException: lib.util.Helper$

Javap はその理由を示しています。[つまり、呼び出しはインライン化されていますが、それでもモジュールを初期化する必要があります。]

私は議論をフォローしていませんが、たとえば、 https ://github.com/scala/scala/pull/1133 にリンクがあり 、バイナリ互換性に関するどのような期待が有効であるかについての ML に関するその他の議論があります。 https://groups.google.com/forum/?fromgroups=#!topic/scala-internals/sJ-xnWL_8PE

于 2012-09-06T16:52:33.317 に答える
0

簡単に言えば、そうしない理由はありません。リンケージは署名の周りで発生します。問題のオブジェクトはコンパイル単位にスコープされているため、クライアントはそれを使用できません (むしろ、使用すべきではありません)。したがって、バイナリ互換性は問題になりません。

于 2012-09-06T15:06:09.357 に答える