uehaj's blog

Grな日々 - GroovyとかGrailsとかElmとかRustとかHaskellとかReactとかFregeとかJavaとか -

Groovyでtapを

InfoQの記事によれば、Ruby 1.9には標準メソッドとしてtapというのがあってUNIXのシェルでいう「tee」コマンドみたいなことができるそうです。tapというのは「盗聴」ですな。
一般にはメソッドの返り値に対してさらにメソッドを呼ぶ、といったシーケンスの途中で、ちょっと値をのぞいてみたりするのに便利とのことです。また、「流れるようなインターフェース」を実現するときのデバッグにも便利とのこと。
Groovyでもやってみました。

class Customer {
  def order
  Order newOrder(){
    order = new Order()
    order
  }
}

class Product {
  String name
}

class Order {
  List lines  = []
  boolean rush
  def with(int qty, String prodName) {
    lines += new OrderLine(qty:qty, prod:new Product(name: prodName))
    this
  }
  def getSkippable() {
    lines[-1].skippable = true
    this
  }
  def getPriorityRush() {
    rush = true
    this
  }
}

class OrderLine {
  boolean skippable = false
  int qty
  Product prod
}

Object.metaClass.tap = {closure->
  closure.call(delegate)
  delegate
}
ExpandoMetaClass.enableGlobally()

def makeFluent(Customer customer) {
      customer.newOrder()
              .with(6, "TAL")
              .tap{ println it.rush }
              .with(5, "HPK").skippable
              .tap{ println it.rush }
              .with(3, "LGV")
              .tap{ println it.rush }
              .priorityRush
              .tap{ println it.rush }
}

def c = new Customer()
makeFluent(c)

なんのことはないでございます。ただ、やってみたかっただけ。

ところで、「fluent interface」の訳語として「輝彩滑刀の流法(モード)」っていかがでしょう。
流行らせたい。


ジョジョの奇妙な冒険 9 (ジャンプ・コミックス)

ジョジョの奇妙な冒険 9 (ジャンプ・コミックス)