ArrayBufferの拡張

最近scala使ってます。便利です。

型推論 と trait と 関数型 がある better java ぐらいの感じでしか使ってないですけど、
触ってて気持ちいい言語です。


でもちょっと scala.vim の自動インデントが微妙です。
よいvimスクリプトがあったら教えてくだしあ(自分で直そう思ったんですが挫折しましたorz)
IDEも使ってみたいんですが、貧弱ネットブックだと重すぎて動きません>_<。誰かmacbookください。


今まで基礎的な文法ばかりやってたので、特に blog のほうに乗せないで
tips みたいなチラシ裏のコードを書き散らしてただけでした。


一応GitHubのほうに今までの tips をうpしてるので何か間違ってるところとかあるとご指摘頂けるとありがたいです(__)


https://github.com/alphaneet/tips-scala


そんなこんなでそれなりに手に馴染んできたので、
そろそろ「これってどうやるんだろ?これで問題ないかな?」って思ったのを blog に書いて
「ちょっとぐぐったらすぐでるよ」レベルのノイズエントリーにならないような予感がしてきましたので(・・・ん?)
scala ネタもぼちぼち書いていきたいと思います。


恥ずかしいこと書いてたらこそっと指摘してくれるとうれしいです

今回のネタ

クラス独自の登録、削除の処理を ArrayBuffer の
+=, ++=, -=, --=, clear メソッド内で呼ばれるようにしてみました。


ArrayBuffer のコード追いかけてみると +=, remove, clear メソッドをそれぞれ override すれば上手く動きそうな感じです。


以下はサンプルコード。インタプリタで実行することを想定しています。
// @see 以下は呼ばれてる(だろうと思われる)APIメソッド名です。
// | 以下は次のAPIメソッドがコールされている箇所の抜粋です。

abstract class Element {
  def register
  def unregister
}

class HogeElement(val n:Int) extends Element {
  def register   = println(n + ": register")
  def unregister = println(n + ": unregister")
  override def toString = n.toString
}

// +=, remove, clear の3つを拡張すれば
// +=, ++=, -=, --=, clear 内で register, unregister は呼ばれる
class ElementArrayBuffer[A <: Element] extends 
      collection.mutable.ArrayBuffer[A] {

  override def +=(elem:A):this.type = {
    super.+=(elem)
    elem.register
    this
  }

  override def remove(n: Int) = { 
    val ret = super.remove(n)
    ret.unregister
    ret
  }

  override def clear {
    foreach { _.unregister }
    super.clear
  }
}

// @see collection.mutable.ArrayBuffer.+=
println("----- new(0 to 5) and += -----")
val buf = new ElementArrayBuffer[HogeElement]
(0 to 5) foreach { i => buf += new HogeElement(i) }

// @see collection.mutable.ArrayBuffer.++=
//  | case _ => super.++=(xs)
// @see collection.generic.Growable.++=
//  | def ++=(xs: TraversableOnce[A]): this.type = { xs foreach += ; this } 
// @see collection.mutable.ArrayBuffer.+=
println("\n----- new(6 to 10) and ++= -----")
buf ++= (6 to 10) map { i => new HogeElement(i) }

// @see collection.mutable.BufferLike.-=
//  | if (i != -1) remove(i)
// @see collection.mutable.remove
println("\n----- find(n==3) and -= -----")
buf find { _.n == 3 } foreach { buf -= }

// @see collection.generic.Shrinkable.--=
//  | def --=(xs: TraversableOnce[A]): this.type = { xs foreach -= ; this }
// @see collection.mutable.BufferLike.-=
//  | if (i != -1) remove(i)
// @see collection.mutable.remove
println("\n----- filter(n>7) and --= -----")
buf --= buf filter { _.n > 7 } 

// @see collection.mutable.ArrayBuffer.clear
println("\n----- clear -----")
buf.clear