Scala2.9ããå°å ¥ããããã¤ããªäºææ§ç¢ºä¿ã®ããã®bridgeã¢ããã¼ã·ã§ã³ã«ã¤ãã¦èª¿ã¹ã
InfoQã®Scala2.9ãªãªã¼ã¹ã®è¨äºãèªãã§ãã¦ãScala2.8ãã2.9ã¸ã®ãã¤ããªäºææ§ç¢ºä¿ã®ããã®æ¹æ³ã«ã¤ãã¦ããããªè¨è¿°ããã£ã
One such technological solution are compiler generated forwarders, so-called bridge methods, which delegate calls from an old to a new method.
http://www.infoq.com/news/2011/05/scala-29
" compiler generated forwarders"ã£ã¦ãªãã?ã¨æã£ã¦èª¿ã¹ã¦ã¿ããå¤åãã®ãããã®Oderskyã®ã¡ã¼ã«ã«ãã@bridgeã¢ããã¼ã·ã§ã³ã®ãã¨ã ã¨æãã
Parallel collections binary compatibility | The Scala Programming Language
Binary compatibility: status and outlook -
scala-user |
Google Groups
ã£ã¦ããã§ã@bridgeã¢ããã¼ã·ã§ã³ã§Scalaã³ã³ãã¤ã©ãã©ããªæåãããã調ã¹ã¦ã¿ãã
Version1
ã¾ãä¸æºåã¨ãã¦ããã¤ããªäºææ§ã®ç¢ºä¿ãå¿ è¦ãªãµã³ãã«ã©ã¤ãã©ãªãç¨æãããé©å½ãªã¨ããã«libã£ã¦ãã£ã¬ã¯ããªãæã£ã¦ãããã«ä»¥ä¸ã®å 容ã§Lib.scalaãç½®ãã¦ã³ã³ãã¤ã«ãã¦ããã"def combine(other:Seq[String]): Unit "ã£ã¦ã¡ã½ãããã²ã¨ã¤ã ãç¨æããã¦ããã·ã³ãã«ãªobjectã ã
lib/Lib.scala
object Lib { def combine(other:Seq[String]): Unit = { println("-- this is first version of combine(other:Seq[String]): Unit") println(other.mkString("/")) } }
ããã¤ãã³ã³ãã¤ã«ãã¦ã¯ã©ã¹ãã¡ã¤ã«ãlibã«ä½ã£ã¦ããã
$ scalac -d lib lib/Lib.scala
次ã«ããã®ãµã³ãã«ã©ã¤ãã©ãªãå©ç¨ããã¯ã©ã¤ã¢ã³ããä½æãããclientãã£ã¬ã¯ããªã«ãããªã«ã³ã¸ã§Mainãªãã¸ã§ã¯ããä½ããä¸ã§ä½ã£ãLib#combineã«ä¾åããããã«ãªã£ã¦ããã
object Main extends App { val seq = Seq("ã¢ãããã£ã¹ã","ãã¦ã³ãã£ã¹ã", "ã¯ãã¹ãã£ã¹ã","éçãã£ã¹ã", "ããªã¼ã ãã£ã¹ã") Lib.combine(seq) }
ã§ããã®client/Main.scalaãã³ã³ãã¤ã«ãã¦ããã
$ scalac -cp lib -d client client/Main.scala
ãã®æç¹ã§ããã¡ã¤ã«/ãã£ã¬ã¯ããªæ§æã¯ãããªã£ã¦ããã
. âââ client â âââ Main$.class â âââ Main$delayedInit$body.class â âââ Main.class â âââ Main.scala âââ lib âââ Lib$.class âââ Lib.class âââ Lib.scala
å®è¡ãã¦ã¿ããã¾ããããªãããªã
[2$ scala -cp lib:client Main -- this is first version of combine(other:Seq[String]): Unit ã¢ãããã£ã¹ã/ãã¦ã³ãã£ã¹ã/ã¯ãã¹ãã£ã¹ã/éçãã£ã¹ã/ããªã¼ã ãã£ã¹ã
ããã¾ã§ä¸æºåã¯çµããã
Version2 å¼æ°ãSeqããTraversableã¸å¤æ´ãã
Lib#combineã®å¼æ°ããSeqããTraversableã¸å¤æ´ãã¦ãã³ã³ãã¤ã«ããã
lib/Lib.scala
object Lib { def combine(other:Traversable[String]): Unit = { println("-- this is first version of combine(other:Traversable[String]): Unit") println(other.mkString("/")) } }
å
ã»ã©ã¨åæ§ã«ã³ã³ãã¤ã«ãã¦ã¯ã©ã¹ãã¡ã¤ã«ãlibã«ä½ã£ã¦ããã
$ scalac -d lib lib/Lib.scala
ã§ããã®Lib#combineã«ä¾åããMainã¯åã³ã³ãã¤ã«ããã«ãå度å®è¡ãã¦ã¿ããããã§ãLibã®ãã¤ããªäºææ§ã¯ç ´å£ããã¦ããã®ã§ãMainã¯å®è¡ã§ããªãã¯ãã
$ scala -cp lib:client Main java.lang.NoSuchMethodError: Lib$.combine(Lscala/collection/Seq;)V at Main$delayedInit$body.apply(Main.scala:5) at scala.Function0$class.apply$mcV$sp(Function0.scala:34) at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) ...
äºæ³éããLib#combineã®ã·ã°ããã£ãå¤æ´ã«ãªã£ããããNoSuchMethodErrorãçºçããã
Version3 bridgeã¡ã½ãããç¨æãã
ãã¤ããªäºææ§ãå£ããã®ã¯ãVersion2ã§combine(other:Seq[String])ãclassãã¡ã¤ã«ããæ¶ããããã ãããã§ãæåã®Seq[String]ãå¼æ°ã«åããã¼ã¸ã§ã³ã復活ãããããã®éã«ã¯ãTraversableãå¼æ°ã«ã¨ãcombineã¸ãã®ã¾ã¾forwardããããã«ãã¦ããããã®ãããªãæ°ããå®è£ ã¸åã«forwardãããããªã¡ã½ããã"bridge method"ã¨ãã¶ã
ãã®bridge methodã«ã@bridgeã¢ããã¼ã·ã§ã³ãä»ãã¦ããã¨å¾ã ãããã¨ãããã
object Lib { import scala.annotation.bridge @bridge def combine(other:Seq[String]): Unit = { println("-- this is first version of combine(other:Seq[String]): Unit") combine(other:Traversable[String]) } def combine(other:Traversable[String]): Unit = { println("-- this is second version of combine(other:Traversable[String]): Unit") println(other.mkString("/")) } }
ã³ã¤ããã³ã³ãã¤ã«ãã¦æ°ããLib.classãä½ãã
$ scalac -d lib lib/Lib.scala
Mainã¯åã³ã³ãã¤ã«ããã«ãå度å®è¡ãã¦ã¿ãã
$ scala -cp lib:client Main -- this is first version of combine(other:Seq[String]): Unit -- this is second version of combine(other:Traversable[String]): Unit ã¢ãããã£ã¹ã/ãã¦ã³ãã£ã¹ã/ã¯ãã¹ãã£ã¹ã/éçãã£ã¹ã/ããªã¼ã ãã£ã¹ã
ããã©ã¯ã¡ããã¨åãããããã¾ã§ã¯ãå½ããåã®è©±ã
Version4 @bridgeã¢ããã¼ã·ã§ã³ã®å¹æ
ããã§ãã·ã°ããã£ãå¤æ´ãã¦ãbridge methodãç¨æããã°ãã¤ããªäºææ§ã¯ç¢ºä¿ã§ãããã¨ãåãã£ãããã¯ã£ããè¨ã£ã¦å¤ãã·ã°ããã£ã®ã¡ã½ããã¯ä½è¨ãªã®ã§ãããããå ãã®Libã©ã¤ãã©ãªãå©ç¨ããã¯ã©ã¤ã¢ã³ãã«ã¯ç¡è¦ãããããã«ããããå®ã¯ããã®ãããªãã¨ãå®ç¾ããããã«@bridgeã¢ããã¼ã·ã§ã³ãåå¨ããã
æ°ããVersion3ã®Libãå©ç¨ããnewclient/NewMain.scalaãç¨æãããã½ã¼ã¹ãã¡ã¤ã«ã®å 容ã¯ããã£ãã®Mainã¨ä¸ç·ã ã
newclient/NewMain.scala
object NewMain extends App { val seq = Seq("ã¢ãããã£ã¹ã","ãã¦ã³ãã£ã¹ã", "ã¯ãã¹ãã£ã¹ã","éçãã£ã¹ã", "ããªã¼ã ãã£ã¹ã") Lib.combine(seq) }
ããããã³ã³ãã¤ã«ãã¦
$ scalac -cp lib -d newclient newclient/NewMain.scala
å®è¡ãããNewMainã§ããcombineã«Seqã渡ãã¦å±
ãã®ã§ãbridge methodãçµç±ãã¦combineãå¼ã³åºãããããºã ã...
$ scala -cp lib:newclient NewMain -- this is second version of combine(other:Traversable[String]): Unit ã¢ãããã£ã¹ã/ãã¦ã³ãã£ã¹ã/ã¯ãã¹ãã£ã¹ã/éçãã£ã¹ã/ããªã¼ã ãã£ã¹ã
ãã®ããã«ããããªãTraversableãå¼æ°ã«åãæ¹ã®combineãå¼ã³åºãããããã®ä»æãã¯ã@bridgeã¢ããã¼ã·ã§ã³ãä»ããã¡ã½ããã«ã¯classãã¡ã¤ã«ã®ä¸ã«ããã®ã¡ã½ããã¯bridge methodã§ããã¨ãããã©ã°ãåãè¾¼ã¾ãããããNewMainãã³ã³ãã¤ã«ããéã«ãScalaã³ã³ãã¤ã©ã¯bridge methodã®ãã©ã°ãä»ããã¡ã½ãããç¡è¦ããããã«ããã®ã§ããã®ãããªçµæã«ãªãã ã¡ãªã¿ã«ã@bridgeã¢ããã¼ã·ã§ã³ãä»ããªãã£ãå ´åã¯ã¡ããã¨å¤ãã·ã°ããã£ã®ã¡ã½ãããçµç±ãã¦å¼ã³åºãããã
ããã§ãå¤ãã·ã°ããã£ã®ã¡ã½ããã«ä¾åããã¯ã©ã¤ã¢ã³ãã¯åã³ã³ãã¤ã«ãªãã«æ°ãããã¼ã¸ã§ã³ã®ã©ã¤ãã©ãªã«ç§»è¡ã§ãããã¤æ°ãããã¼ã¸ã§ã³ã«ä¾åãããã®ã¯bridge methodã®ãªã¼ãã¼ããããªãã«ã©ã¤ãã©ãªãå©ç¨ã§ããç¨ã«ãªãã
TypeSafeã§ã¯ããã®@bridgeã¢ããã¼ã·ã§ã³ãè¦ã¦ãªãããã®å¦çãè¡ã移è¡ãã¼ã«ãéçºãã¦ããããã ã
Version5 å¥å£°
ã£ï¼ã£ãâ¦ãããã©ãããããã¼ï¼ ã²ãã¼ã£ã¯ã¼ã£ãã¼ã£ã±ãããã£ã¯ã¼?ãããã©ãã·ï¼ ãããâ¦ããã¯ã¼ã ãµãï¼ããµã«ãã±ï¼ ã£â¦ããã£ã¼ã¼ã¼ã¼ï¼ï¼ ããã©ãã½ã£ã¼ï¼ï¼ï¼ï¼ï¼ããããã¼ã£ã¯ãããï¼ ã«ã ãï¼ï¼ï¼ã£ã±ããã£ã¯ã«ã ãã©ãã·ï¼ ã¢ãã¢ãã¢ãã¢ãï¼ ã¢ãã¢ãï¼ï¼ï¼ï¼ï¼ï¼ï¼ï¼ããããã¼ã ãï¼ãã ãï¼ï¼ï¼ã¬ã?ã«ã ãã£ãããã â¦ãããã ããµã¼ã¼ï¼ï¼ï¼ ãã£ã±ï¼ããâ¦â¦ãã ãã¼ã¼? ãã£ã±ã ããããã£ãï¼ããã¼ï¼ ãï¼ãã¬ããããã¼ã¼ã£? ããã ããã£ã±ã¼ã¼ã¼â¦ãããã?ã²ãã£ã? ãããã¼ã¼ï¼ ããã¼â¦ã â¦â¦ãããã´ã¼ã¼ã¼ã£ããã ããããã£ã! ããµããã©ãããã£ã¯ã¼ã¼ã£ã¼ï¼ï¼ï¼ï¼ãããã¼ã£ããããããã£â¦ãããã ããããã¼ã£ããµã¼ã£ã¯ã«ã ãããã£ã»ãããããï¼ã¢ãï¼ï¼ï¼ ããã½ã£ã»ã«ãã¼ã¼ã¼ã£ã¯ã«ã ãã¼ã¼ã£â¦ãããã´ã¼ï¼ãã ã â¦ãï¼ ããã·ãã!ãµãã¼ãããã±ã? â¦ããã¯ã«ãã¼ã¼!ã«ã ãã£â¦ããã¼! ãã±ãâ¦ããã©ãã½ã£â¦ãã²ãããï¼ï¼ã«ãã¼ã£ãããµãâ¦ã ã â¦â¦ã? ãï¼ãã ãããããã¯ã«ãã±ã¼ã£ãã ãã¼ï¼ ã»ããããããã¯ãããµããâ¦ãï¼ããããããâ¦ããããããµã«ãã´ã¼ï¼ï¼ãã£ï¼ ã²ããã£ã»ãããã·ï¼ã²ãã´ã¼ï¼ ãã£ãã ããµã ã ããã£ã¯ããããµããã¼ã£ã±ã ã¸ãºãº!ã â¦â¦ã«ã ããã©ãã·ããâ¦â¦ããã©ããâ¦â¦ãï¼ ã ã ï¼ï¼ãï¼ã¸ãº! ã²ããã£ã¼ã¼ï¼ï¼ï¼ãããããï¼ ã£ã¯ãã¼ï¼ ãããããã ãã±ãã! ããºãº! ããããã¼ï¼ããããããã ããµã â¦ããããããã¯ã«ãã¼ï¼ï¼ ãã£â¦ããã´ã¼â¦ãã ããã£ã»ã«ã ããµã ããããããâ¦ã»ãããºï¼ãããããã²ããããµãã¼ï¼ ã¸ãºãºâ¦ â¦ã!ãã â¦ãã ããâ¦ããã©ãããã£ã±ãã£ï¼ï¼ï¼ï¼ ã¢ãï¼ ãµã â¦ãã ããµã¬ããµã«ã ãã£â¦â¦ããï¼ãã ï¼ï¼ ã ï¼ãã ãããµãµãã ã ã â¦â¦ãã©ãã·! ã ï¼ ãããã!ãµãâ¦ããã£ããã¼ï¼ããã£ã ã¬ãã¼ã£ã±ã¼ã£ã¼ï¼ã¢ãã¢ãã¢ãã¢ãï¼ ãããããã! ãã ãï¼ï¼ã ï¼ï¼ï¼ï¼ãã¶ãã£ããã¼ã£ãï¼ ãï¼ã£ãã¼ï¼ï¼ããã½ã£ããã´ã¼ï¼ï¼ï¼ â¦ãã£â¦ããï¼ ã£â¦ããããããã¼ã£ã»ã«ãã´ã¼ï¼ï¼ï¼ï¼ï¼ï¼ ã²ããã£ï¼ã¯ã¼ï¼ ã ãã£ã? ããã£ããã£ããµã ããµãµãµãã²ãã±ããã¯ã¼ã¼ã¼ããã¼ã¼ã ã£ã¼ã¼ï¼ï¼ãã²ãã¼â¦ ãµãµããâ¦ãããã©ããã ãã ã ããã£ãããï¼ï¼ ãã ãã ã â¦ããããããã¼?ããã£ããã¯ã«ã ãã? ã£ãã²ããã£ã¯ã«ãã¼!