Tuple22 限界への対策
今年の初めに Scala の限界に関して書きました:
Scala は
Tuple22までしかサポートしません.
これは Scala が 22個のパラメータを超えた case class を定義できないことを意味します.22個を超えたパーティクルを持つシーケンスを含む複合型を定義するスキーマを扱えるよう回避策をいくつか用意しました.
まず,シーケンスが MaxParticleSize (20)個以上のパーティクルを持つとき,シーケンスを ChunkParticleSize (10)個ごとのチャンク(塊)に分けることにしました.例えば,30個の要素を持つシーケンスは 10個づつの要素を持った三つのチャンクに分かれます:
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<xs:element name="string1" type="xs:string"/>
<xs:element name="string2" type="xs:string"/>
<xs:element name="string3" type="xs:string"/>
...
<xs:element name="string30" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
scalaxb は以上の要素から以下のコードを生成します:
case class Foo(arg1: FooSequence2,
arg2: FooSequence3,
arg3: FooSequence4) {
def string1 = arg1.string1
def string2 = arg1.string2
def string3 = arg1.string3
def string4 = arg1.string4
def string5 = arg1.string5
def string6 = arg1.string6
def string7 = arg1.string7
def string8 = arg1.string8
def string9 = arg1.string9
def string10 = arg1.string10
def string11 = arg2.string11
def string12 = arg2.string12
def string13 = arg2.string13
def string14 = arg2.string14
def string15 = arg2.string15
def string16 = arg2.string16
def string17 = arg2.string17
def string18 = arg2.string18
def string19 = arg2.string19
def string20 = arg2.string20
def string21 = arg3.string21
def string22 = arg3.string22
def string23 = arg3.string23
def string24 = arg3.string24
def string25 = arg3.string25
def string26 = arg3.string26
def string27 = arg3.string27
def string28 = arg3.string28
def string29 = arg3.string29
def string30 = arg3.string30
}
case class FooSequence2(string1: String,
string2: String,
string3: String,
string4: String,
string5: String,
string6: String,
string7: String,
string8: String,
string9: String,
string10: String)
case class FooSequence3(string11: String,
string12: String,
string13: String,
string14: String,
string15: String,
string16: String,
string17: String,
string18: String,
string19: String,
string20: String)
case class FooSequence4(string21: String,
string22: String,
string23: String,
string24: String,
string25: String,
string26: String,
string27: String,
string28: String,
string29: String,
string30: String)
拡張によって複合型が 22個のパーティクルを超えることがあります.XML Schema は型システムの継承に似て,複合型を他の型から拡張することができます.一方,case class を継承することはできません.
<xs:complexType name="barOne">
<xs:sequence>
<xs:element name="int1" type="xs:int"/>
<xs:element name="int2" type="xs:int"/>
<xs:element name="int3" type="xs:int"/>
<xs:element name="int4" type="xs:int"/>
<xs:element name="int5" type="xs:int"/>
<xs:element name="int6" type="xs:int"/>
<xs:element name="int7" type="xs:int"/>
<xs:element name="int8" type="xs:int"/>
<xs:element name="int9" type="xs:int"/>
<xs:element name="int10" type="xs:int"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="barTwo">
<xs:complexContent>
<xs:extension base="barOne">
<xs:sequence>
<xs:element name="int11" type="xs:int"/>
<xs:element name="int12" type="xs:int"/>
<xs:element name="int13" type="xs:int"/>
<xs:element name="int14" type="xs:int"/>
<xs:element name="int15" type="xs:int"/>
<xs:element name="int16" type="xs:int"/>
<xs:element name="int17" type="xs:int"/>
<xs:element name="int18" type="xs:int"/>
<xs:element name="int19" type="xs:int"/>
<xs:element name="int20" type="xs:int"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="barThree">
<xs:complexContent>
<xs:extension base="barTwo">
<xs:sequence>
<xs:element name="int21" type="xs:int"/>
<xs:element name="int22" type="xs:int"/>
<xs:element name="int23" type="xs:int"/>
<xs:element name="int24" type="xs:int"/>
<xs:element name="int25" type="xs:int"/>
<xs:element name="int26" type="xs:int"/>
<xs:element name="int27" type="xs:int"/>
<xs:element name="int28" type="xs:int"/>
<xs:element name="int29" type="xs:int"/>
<xs:element name="int30" type="xs:int"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
通常 barThree は 30個のパラメータを持った違法な case class を生成します.複合型の一つを別の case class に追い出すことで回避することができますが,scalaxb はどれを選ぶかを知り得ません.ここで登場するのが --wrap-contents です.このオプションを使うことでどの複合型を追い出すかを指定することができます.以下が --wrap-contents BarOne を使って scalaxb によって生成したものです:
case class BarThree(arg1: BarOnableSequence2,
int11: Int,
int12: Int,
int13: Int,
int14: Int,
int15: Int,
int16: Int,
int17: Int,
int18: Int,
int19: Int,
int20: Int,
int21: Int,
int22: Int,
int23: Int,
int24: Int,
int25: Int,
int26: Int,
int27: Int,
int28: Int,
int29: Int,
int30: Int) extends BarTwoable {
def int1 = arg1.int1
def int2 = arg1.int2
def int3 = arg1.int3
def int4 = arg1.int4
def int5 = arg1.int5
def int6 = arg1.int6
def int7 = arg1.int7
def int8 = arg1.int8
def int9 = arg1.int9
def int10 = arg1.int10
}