BeginInvoke
BeginInvoke でスレッド作って EndInvoke で wait する。
i@u ~/test/boo> cat invoke.boo import System import System.Threading def hello(): print 'hello' Thread.Sleep(500) print 'world' res = hello.BeginInvoke() print res.IsCompleted hello.EndInvoke(res) print res.IsCompleted i@u ~/test/boo> booi invoke.boo False hello world True
reflection
なんか言語知ってる子が新しい言語環境を覚える時はさっさとリフレクションを修得すべき。 Boo というより C# のドメインなんだろうけど。というわけでさっきの res (型は IAsyncResult とからしい) のメソッド一覧。
i@u ~/test/boo> cat reflection.boo def func(): pass res = func.BeginInvoke() for i in res.GetType().GetMembers(): print i i@u ~/test/boo> booi reflection.boo System.Object get_AsyncState() System.Threading.WaitHandle get_AsyncWaitHandle() Boolean get_CompletedSynchronously() Boolean get_IsCompleted() Boolean get_EndInvokeCalled() Void set_EndInvokeCalled(Boolean) System.Object get_AsyncDelegate() IMessageSink get_NextSink() IMessageCtrl AsyncProcessMessage(IMessage, IMessageSink) IMessage GetReplyMessage() Void SetMessageCtrl(IMessageCtrl) IMessage SyncProcessMessage(IMessage) Boolean Equals(System.Object) Int32 GetHashCode() System.Type GetType() System.String ToString() System.Object AsyncState System.Threading.WaitHandle AsyncWaitHandle System.Boolean CompletedSynchronously System.Boolean IsCompleted System.Boolean EndInvokeCalled System.Object AsyncDelegate System.Runtime.Remoting.Messaging.IMessageSink NextSink
ついでにコンテナをなめる処理が出てきたので次に続く。
foreach
コンテナから全部取り出すのは for variable in container で良い。
i@u ~/test/boo> cat foreach.boo for i in (1,2,3): print i for i in [1,2,3]: print i for i in {'a':1, 'b':2, 'c':3}: print i.Key print i.Value i@u ~/test/boo> booi foreach.boo 1 2 3 1 2 3 c 3 a 1 b 2
そろそろムラムラと iosh みたいな、補完機能つきのインタラクティブシェルが作りたくなってきました。非常にガイシュツの予感ですが。
generator expression
i@u ~/test/boo> cat generator.boo for i in x*x for x in range(5): print i i@u ~/test/boo> booi generator.boo 0 1 4 9 16
後置 for とかに見えますが、 x*x for x in range(5) が、 generator オブジェクトで、それを巡回している、と。ふむ。
generator method
Fiber とか coroutine とかいうヤツ。さっきと等価なもの。
i@u ~/test/boo> cat gen_method.boo def gen(): for x in range(5): yield x*x for i in gen(): print i i@u ~/test/boo> booi gen_method.boo 0 1 4 9 16
高階?ジェネレータを書いてみる。 Enumerable を取ってジェネレータを返すと良い。
i@u ~/test/boo> cat gen_gen.boo def gen(g): for x as int in g: yield x*x for i in gen(gen(gen(range(5)))): print i i@u ~/test/boo> booi gen_gen.boo 0 1 256 6561 65536
macro
マクロは自分で C# 書いたら定義できるっぽいのが面白そうなんだけど今やるのはちょとめどい。
http://boo.codehaus.org/Part+17+-+Macros
print, assert, using, lock, debug ってのがマクロだそうだ。 print は print 、 debug は printf デバッグ用の物体の模様。 assert は assert 。
それはいいとして、 using が let で lock が synchronized なわけで、こういうのをマクロにするってのは見たことがなくて、なんか面白い発想だなーと思った。あ、いや、 LISP の発想か。
http://boo.codehaus.org/Syntactic+Macros
with 節を自分で定義とか、実にいい感じ。ああ素敵だ。
duck
普段は型推論つきの静的型付け言語で、 as duck とした部分だけ Ruby とか ObejctiveC みたいな世界に突入する、と。
i@u ~/test/boo> booi duck.boo duck.boo(6,9): BCE0019: Boo.Lang.Compiler.CompilerError: 'Length' is not a member of 'System.Object'. i@u ~/test/boo> cat duck.boo i = 1 // i = "1" // これはできない。 i は int になってるから。 o as object = 1 o = "1" // print o.Length // これはできない。 object に size というメソッドが無いから。 d as duck = 1 d = "1" // 大丈夫なのよさ。 print d.Length // 大丈夫なのよさ。 i@u ~/test/boo> booi duck.boo 1
うん素晴らしい。
variable in string literal
Ruby では #{} が ${} になる。
i@u ~/test/boo> cat lit_var.boo i = 1 print "i = ${i}" i@u ~/test/boo> booi lit_var.boo i = 1
つーわけで Boo Primer はだいたい読んだ。