Java.use(better); Episode#22 ファインダーを作成する

前の記事記事一覧|次の記事》
Java.use(better, Scala);


Episode#22

ファインダーを作成する:履歴を残す



@父親が、子供達にできる最も重要なことは
@子供達の母親を愛することだ
The most important thing a father can do for his children is to love their mother.
Theodore Hesburgh - Wikipedia

《関連記事》

■ 事例:class UpperCase

次の事例は、その理解を深めるための便宜的なものです。trait Iterator で規定した、少数の抽象メソッド hasNext/next を実現するだけで、多数のメソッド(foreach,map,filter,zip など)を利用できます。

class UpperCase(s: String) extends Iterator[Char] {
  var c = 0
  def hasNext = c < s.size
  def next() = { val r = s(c).toUpper; c += 1; r }  
}

UpperCase は、特定の文字列 s を大文字に変換して、各文字を巡回します。

scala> new UpperCase("abc") foreach print
ABC

メソッド foreach を利用すると、各要素(大文字)を順に出力できます。また、

scala> for (e <- new UpperCase("abc")) print(e)
ABC

for 式でも同じことができます。さらに、

scala> new UpperCase("abcde")
...
scala> . foreach { e => if (e.toInt%2 != 0) print(e) }
ACE

scala> new UpperCase("abcde") filter { _.toInt%2 != 0 }
...
scala> . foreach { print }
ACE

foreach に代えて、filter を利用すると、特定の条件を満たす要素だけを巡回できます。そして、

scala> new UpperCase("abc") map { _.toInt%5 }
...
scala> . foreach { print }
012

scala> print( new UpperCase("abcde") map {
     |   _.toInt%5
     | } mkString(",") )
0,1,2,3,4

メソッド map を利用すると、巡回した要素に特定の関数を適用して得られる要素を列挙できます。

scala> new UpperCase("abc").zip(new UpperCase("12345"))
...
scala> . foreach { print }
(A,1)(B,2)(C,3)

scala> new UpperCase("abcde").zip(new UpperCase("789"))
...
scala> . foreach { print }
(A,7)(B,8)(C,9)

メソッド zip を利用すると、要素を巡回するときに、他の要素と組み合わせて利用できます。その引数には、Iterator に準拠するものを指定できます。ただし、どちらか一方の要素がないと、他方の要素も無視します。

scala> new UpperCase("abc").zip(1 to 3 iterator) foreach {
     |   case (e,f) => print(e+""+f)
     | }
A1B2C3
scala> print( new UpperCase("abc").zip(1 to 3 iterator) map {
     |   case (e,f) => (e+"")*f
     | } mkString(",") )
A,BB,CCC

パターンマッチングを利用して、各要素を参照するときには、タプルパターン case(e,f) を指定します。

■ 未来への考察

Scala では、インスタンスを生成するときに、そのブロック内で初期値を設定するだけでなく、任意の処理を記述できるので、コードが簡潔で見通しが良くなります。プログラム(算譜)が大きく複雑になると、プログラミング(作譜)の効率が悪く、バグの温床になりかねないので、この特徴は重宝します。

オブジェクトごとに最適な制御構造を実現するための仕掛が、trait Iterator に用意してあるので、少数の抽象メソッドを実現するだけで、多数のメソッド群を利用できます。というのも、抽象メソッド hasNext/next だけで実現されているので、具象クラスに依存しない抽象表現になっているからです。必要なら、具象クラスでそのメソッドを最適化できます。

オブジェクト指向の醍醐味は「オブジェクトごとに最適な制御構造」を再定義できることです。最適化した制御構造を活用するときには、同じメッセージに呼応して、その状況で最適な問題解決が図れるかで、プログラマーの力量が問われます。それが可能になるのは、制御メッセージの解釈を、コンパイラーに委ねるのではなく「オブジェクト自身が判断する」仕掛を用意できるからです。

料理のレシピがあると、調理する順番に沿った手順の一覧を確認できて便利です。が、実際には、素材の状態に合わせたり、代用となる素材を探したりなど、料理人には、その状況を見極める技能が求められます。それは、プログラマーにも通じるものがあります。

》作業中です《

 ↑ TOP

Created: 2010/05/23|Last updated: 2013/07/14 09:28:51