Created
July 16, 2012 02:42
-
-
Save tototoshi/3120089 to your computer and use it in GitHub Desktop.
trouble with jgit & scala.collection.JavaConversions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// import scala.collection.JavaConversions._ | |
scala> val git = new Git(new FileRepositoryBuilder().findGitDir(new java.io.File("/path/to/repos")).readEnvironment().build()) | |
git: org.eclipse.jgit.api.Git = org.eclipse.jgit.api.Git@18ed36fb | |
scala> git.log.addPath("foo").call.head | |
res49: org.eclipse.jgit.revwalk.RevCommit = commit c4554d9f46de49e449242a2aa75d39874dc99498 1342332998 ----sp | |
scala> git.log.addPath("foo").call.headOption | |
res50: Option[org.eclipse.jgit.revwalk.RevCommit] = Some(commit d3107ef998b25d70f86f1a5d530c31c02507d59e 1342012813 ----sp) | |
scala> git.log.addPath("foo").call.toList.head | |
res51: org.eclipse.jgit.revwalk.RevCommit = commit c4554d9f46de49e449242a2aa75d39874dc99498 1342332998 ----sp | |
scala> git.log.addPath("foo").call.toList.headOption | |
res52: Option[org.eclipse.jgit.revwalk.RevCommit] = Some(commit c4554d9f46de49e449242a2aa75d39874dc99498 1342332998 ----sp) | |
scala> git.log.addPath("foo").call.toList | |
res53: List[org.eclipse.jgit.revwalk.RevCommit] = List(commit c4554d9f46de49e449242a2aa75d39874dc99498 1342332998 ----sp, commit d3107ef998b25d70f86f1a5d530c31c02507d59e 1342012813 ----sp) | |
// headOption fetches second element?? |
https://github.com/scala/scala/blob/v2.9.2/src/library/scala/collection/JavaConversions.scala#L401
https://github.com/scala/scala/blob/v2.9.2/src/library/scala/collection/JavaConversions.scala#L587
JIterableWrapper
がつくられる
isEmpty
が呼ばれる
https://github.com/scala/scala/blob/v2.9.2/src/library/scala/collection/IterableLike.scala#L81-82
https://github.com/scala/scala/blob/v2.9.2/src/library/scala/collection/IterableLike.scala#L63
isEmpty
のために新しいiteratorがつくられる(そのiteratorが先頭の要素保持しちゃう)
head
呼ぶ
https://github.com/scala/scala/blob/v2.9.2/src/library/scala/collection/IterableLike.scala#L72
head
の中で呼ばれる foreach
も新しいIterator生成するが、 isEmpty
のときに生成した Iterator が先頭の要素を保持というか消費してて、二回目にここで生成したiteratorは、2番目の要素が先頭になってる
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
call
が返す、java.lang.Iterable
型のオブジェクトのiterator
のメソッドの実装がiterator
というメソッドを呼ぶ度に毎回新しいIteratorを生成して返すのではなく、
call
が返したIterable
型のオブジェクトからは、1度しかiteratorメソッドを呼べない (複数回呼んでも、すでに中途半端に消費されたIteratorが返ってくる可能性あり)っていう実装になってるみたい。
scala側は、毎回新しいIteratorが返る ことを前提で実装してるのでこうなる。
これが一般的に java での Itetable や Iterator の規約違反なのかどうかはしらぬ・・・(まぁなんか個人的にはおかしい気がするけど)
http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/Iterable.html
言い換えると、ある意味、
call
が返すjava.lang.Iterable
型のオブジェクト自体が状態を持ってるjgit の javadoc にはそれが書いてあるのか・・・
https://github.com/eclipse/jgit/blob/aeb28b1f3e8763c006dd26e690fbcad0920bc1a4/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java#L105-109
だったらこれ、もう最初から Iterator 返せばいいのに・・・