ScalaでRubyのObject#tapがぽぽぽぽ〜ん。っていうかいつでもmapしたい
「まほうのこーどで♪ たのしい♪ れいがいが♪ ぬるぽぽ〜ん♪ 」
作ってみた。
// 入れ物はタッパーです。 trait Tapper[A] { val obj:A // RubyのObject#tap的な。引数fに自分自身を適用させて自身を返す。 // 副作用専用メソッド。nullだったらなにもしなーい def tap(f:A => Unit):A = { Option(obj).foreach(f);obj } // 上記の、戻り値Option版。nullだったらNoneが返る def tapOption(f:A => Unit):Option[A] = { Option(obj).foreach(f);Option(obj) } // いつでもmapできたら便利よね? def map[B](f:A => B):Option[B] = Option(obj).map(f) // Option(obj)でもいいけど、何でもメソッドチェーンしたい病の人に def toOption:Option[A] = Option(obj) } // implict conversionで、タッパーに詰める implicit def any2Tapper[A](a:A):Tapper[A] = new Tapper[A]{ val obj = a }
こういう風に使えば。nullとか気にしないでよくなるよねー。ぽぽぽぽ〜ん。まぁこの例のカレンダーだったらブロックに初期化処理を詰めてもいんだけどね。nullチェックとかウザいし。
scala> import java.util.Calendar import java.util.Calendar scala> val c1 = Calendar.getInstance.tap{ c => | c.add(1, Calendar.MONTH ) | c.add(1, Calendar.YEAR ) | } c1: java.util.Calendar = java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Tokyo",offset=32400000,dstSavings=0,useDaylight=false,transitions=10,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=4,DAY_OF_MONTH=23,DAY_OF_YEAR=82,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=4,AM_PM=1,HOUR=1,HOUR_OF_DAY=13,MINUTE=30,SECOND=19,MILLISECOND=552,ZONE_OFFSET=32400000,DST_OFFSET=0] scala> (new java.text.SimpleDateFormat).map { fmt => fmt.format(c1.getTime) } res0: Option[java.lang.String] = Some(14/03/23 13:30) scala> val c2:Calendar = null c2: java.util.Calendar = null scala> val c3 = c2.tap{ c => | c.add(1, Calendar.MONTH ) | c.add(1, Calendar.YEAR ) | } c3: java.util.Calendar = null