前に紹介した方法で、scala-2.9.0.r24265-b20110211020037を落として試してみた(`・ω・´)/
なお、ただnightly試しただけなので、2.9のRCとか正式版がでるころには、情報古くなって変わっていることがあるかもしれないので注意(´・ω・`)
まず、repl起動
C:\scala\scala-2.9.0.r24265-b20110211020037\bin>scala Welcome to Scala version 2.9.0.r24265-b20110211020037 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20). Type in expressions to have them evaluated. Type :help for more information.
とりあえずhelp
scala> :help All commands can be abbreviated - for example :he instead of :help. :cp add an entry (jar or directory) to the classpath :help print this help message :history [arg] show the history (optional arg: lines to show) :h? search the history :implicits show the implicits in scope (-v to include Predef) :javap disassemble a file or class name :keybindings show how ctrl-[A-Z] and other keys are bound :load load and interpret a Scala file :power enable power user mode :quit exit the interpreter :replay reset execution and replay all previous commands :sh fork a shell and run a command :silent disable/enable automatic printing of results
- implicits
- javap
- keybindings
っていうのが増えてる(・ω・)
keybindings打ってみる
scala> :keybindings Reading jline properties for default key bindings. Accuracy not guaranteed: treat this as a guideline only. 1 CTRL-A: move to the beginning of the line 2 CTRL-B: move to the previous character 3 CTRL-C: toggle overtype mode (frankly, I wasn't sure where to bind this) 4 CTRL-D: close out the input stream 5 CTRL-E: move the cursor to the end of the line 6 CTRL-F: move to the next character 7 CTRL-G: move to the previous word 8 CTRL-H: delete the previous character 9 TAB, CTRL-I: signal that console completion should be attempted 10 CTRL-J, CTRL-M: newline 11 CTRL-K: erase the current line 12 CTRL-L: clear screen 13 ENTER: newline 14 CTRL-N: scroll to the next element in the history buffer 15 CTRL-O: move to the previous word 16 CTRL-P: scroll to the previous element in the history buffer 18 CTRL-R: search backwards in history 19 CTRL-S: Move to the end of the history 21 CTRL-U: delete all the characters before the cursor position 22 CTRL-V: paste the contents of the clipboard (useful for Windows terminal) 23 CTRL-W: delete the word directly before the cursor 27 CTRL-[: escape - clear the current line. 127 CTRL-?: delete the previous character
ほほぅ
implicitsは?
scala> :implicits No implicits have been imported other than those in Predef.
まだPredefで定義された物以外なにもないって言われた(´・ω・`)
そういえば、こないだのscala東北で、try catchの部分の仕様変わった(というか拡張された)って言ってたので試してみる
scala> val pf:PartialFunction[Exception,Unit] = {case e:Exception => println( "例外catchしたお(`・ω・´)" ) } pf: PartialFunction[Exception,Unit] = <function1> scala> try{ | throw new Exception | }catch{ | pf | } <console>:12: error: type mismatch; found : java.lang.Throwable required: Exception pf ^
なんか、微妙なエラー・・・(´・ω・`)
今度はThrowableでやってみる
scala> val pf:PartialFunction[Throwable,Unit] = {case e:Exception => println( "例外catchしたお(`・ω・´)" ) } pf: PartialFunction[Throwable,Unit] = <function1> scala> try{ | throw new Exception | }catch{ | pf | } 例外catchしたお(`・ω・´)
おぉぉぉ、成功したっぽい。
こんな感じで、2.9からは、catchの部分にThrowableを引数にとるPartialFunctionを書けるようになるらしいですよ
こんなことも・・・
scala> try 2 catch pf finally println("hoge") hoge res6: AnyVal = 2
- tryとcatchの間
- catchとfinallyの間
- finallyの後
の中括弧が全部省略できる。っていうか調べたら、
- tryとcatchの間
- finallyの後
の中括弧を省略できるのは、もとからですね(・ω・`)
これで、catchとfinallyの間の中括弧も省略できることによって、ますます難読化でき・・・(違っ
ではなく、括弧が省略出来るっていうのは、
式がひとつの場合に、括弧省略できる
っていう原則を採用してるからですかね?メソッドなんかもそうですが。
caseの部分がPartialFunctionに出来ることについての利点ですが、まぁ例外部分の処理を、直接そこに書くのではなく、PartialFunctionにすることによって色々と柔軟性が増すんじゃないでしょうか?*1
そういえばまえに、自分の中でcaseの使い方を整理してたときに、
例外の部分てPartialFunctionの記述のしかたと、全く同じじゃないか?
と密かに気づいたことがあったのですが、もともと、こんな風PartialFunctionを受け取れるようにする予定があったんですかね?
わざわざ前のエントリで
例外のcaseはたぶんべつだから5種類じゃね?
ってあとから気づいて追記したんですが、この新文法のおかげで、ある意味、例外のcatchの部分には、
PartialFunctionリテラル*2を書いている
のと区別がつかなくなるわけですよね?*3
で、内部実装調べるために、以下のようなソースをコンパイル&jadで逆コンパイルしてみた
object Test{ val pf:PartialFunction[Throwable,String] = {case e:Exception => "例外catchしたお(`・ω・´)" } val a = try "scalaちゃん" catch pf }
//関係ないところは省略 private final String liftedTree1$1() { String exceptionResult1 = null; exceptionResult1 = "scala\u3061\u3083\u3093"; break MISSING_BLOCK_LABEL_41; Exception exception; exception; PartialFunction catchExpr1 = pf(); if(!catchExpr1.isDefinedAt((Object)exception)) break MISSING_BLOCK_LABEL_43; exceptionResult1 = (String)catchExpr1.apply((Object)exception); return exceptionResult1; throw exception; } private final String a = liftedTree1$1();
いや・・・わかんねぇ・・・jadェ・・・
じゃあJava Decompilerで(`・ω・´)つ
// ERROR // private final String liftedTree1$1() { // Byte code: // 0: aconst_null // 1: astore_1 // 2: ldc 29 // 4: astore_1 // 5: goto +36 -> 41 // 8: astore_2 // 9: aload_0 // 10: invokevirtual 31 Test$:pf ()Lscala/PartialFunction; // 13: astore_3 // 14: aload_3 // 15: aload_2 // 16: checkcast 33 java/lang/Object // 19: invokeinterface 39 2 0 // 24: ifeq +19 -> 43 // 27: aload_3 // 28: aload_2 // 29: checkcast 33 java/lang/Object // 32: invokeinterface 45 2 0 // 37: checkcast 47 java/lang/String // 40: astore_1 // 41: aload_1 // 42: areturn // 43: aload_2 // 44: athrow // // Exception table: // from to target type // 2 8 8 finally }
よけいわかんねぇ・・・
あと、DelayedInitていうの継承すると、コンパイラが特殊処理するようになるとか、他にも色々新機能あるらしいですが、後で気が向いたら試してみます