正規表現パターンマッチングを行う次のコードがあります。
class UserAgent(val ua: String) {
val iOS = """.*(iPad|iPhone|iPod).*OS ([0-9_]+).*""".r
val Android = """.*Android ([0-9.]+).*""".r
val WindowsPhone = """.*Windows Phone OS.*""".r
val WebOS = """.*webOS.*""".r
val BlackBerry = """.*BlackBerry.*""".r
val WAPBrowser = """.*(MIDP|UP\.Browser|Obigo|Polaris|BREW|Brew|NetFront).*""".r
var platform = "UnknownPlatform"
var platformVersion = "UnknownVersion"
ua match {
case iOS(_, version) => {
platform = "IOS"
platformVersion = version.replace("_", ".")
}
case Android(version) => {
platform = "Android"
platformVersion = version
}
case WindowsPhone() => platform = "WindowsPhone"
case WebOS() => platform = "WebOS"
case BlackBerry() => platform = "BlackBerry"
case WAPBrowser(p) => platform = "WAPBrowser"
}
}
(簡略化された)コードでテストできるもの:
val tests = for (
str <- List("Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7",
"Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
"bla bla Windows Phone OS bla bla",
"bla bla webOS bla bla",
"bla bla BlackBerry bla bla",
"LG-LX600 Polaris/6.0 MMP/2.0 Profile/MIDP-2.1 Configuration/CLDC-1.1")
) yield new UserAgent(str)
tests foreach { ua => println(ua.platform + " " + ua.platformVersion) }
私のクラスUserAgent
には変更可能な変数platform
とplatformVersion
. 私が達成したいのは、不変性を持たせることです。そのため、 a のようなものtrait
を定義platform
し、platformVersion
異なる値を返すサブクラスを定義します。私が見逃しているのは、そのようなサブクラスをインスタンス化して返すコンストラクターを作成する方法です。