Scalaの「private object」「protected object」
コメント欄で、「クラスのアクセス修飾子はパッケージに対してのものだよ」と教えていただいたので、さらに突っ込んで色々と実験してみました。
発見したことを並べておきます。
複数のパッケージ宣言を1つのファイルで行える
コメント欄で教えてもらったまんまなのですが、ソースファイルをパッケージごとにフォルダ分けしておかなくてもコンパイルできます。
さらに、1ファイルの中に複数のパッケージ宣言を書けます。複数のパッケージを宣言するときは、パッケージ全体をニョロカッコで囲む必要があります。
package aomori { object apple } package akita { object namahage } println( aomori.apple ) println( akita.namahage )
ネストしたパッケージを1ファイルの中に書くときは、ネストして書かないといけない
下のように書くとコンパイルエラーが出ます。
package japan.tokyo { object hiyoko } package japan.akita { object hatahata }
こう書かないといけない
package japan { package tokyo { object hiyoko } package akita { object hatahata } }
複数ファイルに分けて書くなら大丈夫
// hiyoko.scala package japan.tokyo object hiyoko
// hatahata.scala package japan.tokyo object hatahata
「パッケージの一番上」を明示的に表す「_root_」というパッケージがある
下の二行は全く同じ意味。
println( japan.akita.hinaidori ) println( _root_.japan.akita.hinaidori )
private object は、他のパッケージから参照できないオブジェクト
private をつけて宣言したオブジェクトは、同一パッケージからは参照できるけど、他のパッケージからは参照できない。
ただし、パッケージの階層構造で、オブジェクトが宣言されたパッケージの下にぶらさがっているパッケージからは参照できる。
こんな感じ(見づらいなあ…)
// kamakura.scala package japan.akita private object kamakura // japan.akita パッケージの kamakura オブジェクト
// japan_akita_yokote_main.scala package japan.akita.yokote object main { // japan.akita.yokote パッケージの main オブジェクト def main(args: Array[String]) { println( japan.akita.kamakura ) // 参照できる } }
protected object はよくわかんない
protected object を、宣言されたパッケージの下にぶらさがってるパッケージの中から参照したら、コンパイラがエラーになってしまった。
// kiritanpo.scala package japan.akita protected object kiritanpo // japan.akita パッケージの kiritanpo オブジェクト
// japan_akita_oodate_main.scala package japan.akita.oodate object main { // japan.akita.oodate パッケージの main オブジェクト def main(args: Array[String]) { println( japan.akita.kiritanpo ) } }
秋田県の大館市パッケージの中から、秋田県パッケージのプロテクトきりたんぽを参照しようとしたら、コンパイラが大量のエラーを吐いて死んでしまいました。
$ scalac kiritanpo.scala $ scalac japan_akita_oodate_main.scala Exception in thread "main" java.util.NoSuchElementException: head of empty list at scala.Nil$.head(List.scala:1244) at scala.Nil$.head(List.scala:1241) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.accDefBuf(SuperAccessors.scala:44) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.makeAccessor(SuperAccessors.scala:283) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.transform(SuperAccessors.scala:189) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer$$anonfun$1.apply(SuperAccessors.scala:58) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer$$anonfun$1.apply(SuperAccessors.scala:55) at scala.List$.map2(List.scala:287) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.transformArgs(SuperAccessors.scala:55) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.transform(SuperAccessors.scala:207) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform$5.apply(Trees.scala:1290) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform$5.apply(Trees.scala:1289) at scala.tools.nsc.ast.Trees$Transformer.atOwner(Trees.scala:1405) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:33) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:27) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.atOwner(SuperAccessors.scala:224) at scala.tools.nsc.ast.Trees$Transformer.transform(Trees.scala:1288) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:46) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.transform(SuperAccessors.scala:213) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transformTrees$1.apply(Trees.scala:1381) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transformTrees$1.apply(Trees.scala:1381) at scala.List$.loop$1(List.scala:254) at scala.List$.mapConserve(List.scala:271) at scala.tools.nsc.ast.Trees$Transformer.transformTrees(Trees.scala:1381) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer$$anonfun$3.apply(SuperAccessors.scala:112) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer$$anonfun$3.apply(SuperAccessors.scala:112) at scala.tools.nsc.ast.Trees$Transformer.atOwner(Trees.scala:1405) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:33) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:27) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.atOwner(SuperAccessors.scala:224) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.transform(SuperAccessors.scala:112) at scala.tools.nsc.ast.Trees$Transformer.transformTemplate(Trees.scala:1383) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform$3.apply(Trees.scala:1281) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform$3.apply(Trees.scala:1281) at scala.tools.nsc.ast.Trees$Transformer.atOwner(Trees.scala:1405) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:33) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:27) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.atOwner(SuperAccessors.scala:224) at scala.tools.nsc.ast.Trees$Transformer.transform(Trees.scala:1280) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:46) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.transform(SuperAccessors.scala:102) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:1399) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:1397) at scala.List$.loop$1(List.scala:254) at scala.List$.mapConserve(List.scala:271) at scala.tools.nsc.ast.Trees$Transformer.transformStats(Trees.scala:1397) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform$1.apply(Trees.scala:1273) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform$1.apply(Trees.scala:1273) at scala.tools.nsc.ast.Trees$Transformer.atOwner(Trees.scala:1405) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:33) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:27) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.atOwner(SuperAccessors.scala:224) at scala.tools.nsc.ast.Trees$Transformer.transform(Trees.scala:1272) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:46) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.transform(SuperAccessors.scala:213) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:1399) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:1397) at scala.List$.loop$1(List.scala:254) at scala.List$.mapConserve(List.scala:271) at scala.tools.nsc.ast.Trees$Transformer.transformStats(Trees.scala:1397) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform$1.apply(Trees.scala:1273) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform$1.apply(Trees.scala:1273) at scala.tools.nsc.ast.Trees$Transformer.atOwner(Trees.scala:1405) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:33) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:27) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.atOwner(SuperAccessors.scala:224) at scala.tools.nsc.ast.Trees$Transformer.transform(Trees.scala:1272) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:46) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.transform(SuperAccessors.scala:213) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:1399) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transformStats$1.apply(Trees.scala:1397) at scala.List$.loop$1(List.scala:254) at scala.List$.mapConserve(List.scala:271) at scala.tools.nsc.ast.Trees$Transformer.transformStats(Trees.scala:1397) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform$1.apply(Trees.scala:1273) at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform$1.apply(Trees.scala:1273) at scala.tools.nsc.ast.Trees$Transformer.atOwner(Trees.scala:1405) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:33) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:27) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.atOwner(SuperAccessors.scala:224) at scala.tools.nsc.ast.Trees$Transformer.transform(Trees.scala:1272) at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:46) at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.transform(SuperAccessors.scala:213) at scala.tools.nsc.ast.Trees$Transformer.transformUnit(Trees.scala:1400) at scala.tools.nsc.transform.Transform$Phase.apply(Transform.scala:30) at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:247) at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:233) at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:233) at scala.Iterator$class.foreach(Iterator.scala:387) at scala.collection.mutable.ListBuffer$$anon$1.foreach(ListBuffer.scala:255) at scala.tools.nsc.Global$GlobalPhase.run(Global.scala:233) at scala.tools.nsc.Global$Run.compileSources(Global.scala:545) at scala.tools.nsc.Global$Run.compile(Global.scala:629) at scala.tools.nsc.Main$.process(Main.scala:86) at scala.tools.nsc.Main$.main(Main.scala:107) at scala.tools.nsc.Main.main(Main.scala)
これは報告した方がいいのかな…