2011-10-14 [プログラミング] Google の新言語 Dart 
Google の新言語 Dart でいろいろ遊んでみた。
予約語のように思えた abstract、class、static 、 final 、 get なんかが予約語じゃなくてびっくりした。JavaScript からのポーティングを容易にするためなんだって!本気で JavaScript の置き換え目指しているんだな。
ちょっと勉強しただけだけど下記のような点が印象に残った。
・ Generics を使える
・ 静的型言語と動的型言語の両方の書き方ができる。
・ Dynamic 型とかいいね。
・ シングルクオート3つとかダブルクオート3つの複数行文字列がある
・ 文字列中に ${任意の式} のように書く String Interpolation が可能
・ 数は int 型と double 型
・ int は int32_t でも int64_t でもなく任意の長整数を表現可能
・ 暗黙の型変換が boolean conversion 以外にない
・ JavaScript とは違う
・ 単に int i と書いた場合は、i は 0 ではなく null
・ ちゃんと closure は使える
・ static メソッドとか static 変数は override したり hide したりできない
・ 継承するクラスは、基底クラスの内部実装も気にせなあかんということなんかな
・ 常に単一スレッドで動く
・ スレッドの概念がない代わりに isolates という概念がある
・ isolates は Erlang のプロセスみたいなもの?
ライブラリの方も興味深い。
・ 普通に num 型にメソッドがある。Ruby みたいなかんじ
・ 100.toRadixString(16) が "64" になるみたいな書き方
・ 文字列連結のための StringBuffer 型、immutable な String 型がある
・ Queue は Double Ended Queue
・ 最初の要素を取り出すのは shift() ではなく removeFirst()
・ 最後の要素を取り出すのは pop() ではなく removeLast()
・ メソッドオーバーロードで << を再定義したくなるかんじ
・ RegExp クラスがある。使い方はめんどそう。
RegExp exp = const RegExp(@"(\w+)"); String str = "Parse my string"; Iterable<Match> matches = exp.allMatches(str, exp);
・そういや、String クラスが Pattern インタフェースを実装している
・ String クラスでも 上の allMatches() メソッドが使えるみたい。
・ Collection インタフェースに foreach() メソッドとかがある。
・ List クラス、Queue クラス、Set クラスとかで使える
・ Promise クラスがある。JSDeferred みたいなかんじ?
・ Dispatcher、Isolate 、ReceivePort 、SendPort が面白そう
けど、いろいろやってみたけど私だったら Dart を使わず、Coffee Script を使うかなぁ。
理由は、
・ JavaScript のオブジェクトと挙動が全然違う
main(){
var obj = {};
obj["attribute"] = 1;
print(obj["attribute"]); // 正常実行される
print(obj.attribute); // 失敗する
}
・ オープンクラスじゃないから既存のクラスにメソッド追加とかはできない
・ "と'の違いじゃなくて、 @ で string interpolation の有無を区別する
main(){
var world = "World!";
print("Hello, ${world}"); // Hello, World!
print(@"Hello, ${world}"); // Hello, ${world}
print('Hello, ${world}'); // Hello, World!
print(@'Hello, ${world}'); // Hello, ${world}
}
・メタプログラミング的なことができない
・ せめて、typeof くらいは欲しいんだけど・・・。
・ for(var i in obj) でオブジェクトの要素を取得することもできない
・ foreach はあるけど、Java 的なイテレータのための Syntax sugar
・DSL向けじゃない
・ CoffeeScript は、() をわりと省略できるのが気に入っていたり。
・; を忘れたらバッチリ怒られる。
・ めんどい
全体的に、一人で JavaScript を書く程度のレベルであれば発生しないようなコーディング規約とか、他人のソースコードを読めない的な問題を解決するために作られた言語という印象。
Java の人は豊富にいるけど、JavaScript の人はあんましいない開発陣でチーム開発する場合とかは向いているのかもしんない。
JavaScript 技術力が高い開発者だったら、JavaScript でできるのに Dart でできないことがいっぱいあることが気になっちゃいそう。
2011-05-22 [プログラミング] メタプログラミングRuby読書会 第2回
■[プログラミング] メタプログラミングRuby読書会 第2回 
メタプログラミングRuby の中で、カレントクラスという用語が説明されていましたが、
説明が分かりにくいように感じたので新たに整理していこうと思います。
カレントクラスとは、def method_name args ... end のような書き方で、メソッドが定義される場所のことです。
カレントクラスは次のように考えることができます。
- クラスのコンテキストであれば、現在のクラス
- オブジェクトのコンテキストであれば、self のオブジェクトの特異クラス
クラスのコンテキストに遷移する方法は次の2通りあり、その場合はそのクラスがカレントクラスになります。
- class または module キーワードでクラス(モジュール)をオープンする
- class_eval でレシーバのクラスをオープンする
逆にオブジェクトのコンテキストに遷移するには、instance_eval を使うことになります。この場合はそのオブジェクトの特異クラスがカレントクラスになります
つまり、 instance_eval の中の def はそのオブジェクトの特異メソッド定義になります
クラスのコンテキストへの遷移の中で特に、class <<obj ... end という記法があります。そのオブジェクトの特異クラスを開くときに使う特別な記法です。
このような説明よりも、下記のようなソースを見るとわかりやすいかもしれません。
# (1) トップレベルのメソッド定義( Object に定義される) def toplevel_method end # (2) クラスのコンテキストでのメソッド定義 # クラスA のインスタンスメソッドとして定義される class A def instance_method1 end end # (3) class_eval を利用してクラスのコンテキストでメソッド定義 # クラスA のインスタンスメソッドとして定義される A.class_eval do def instance_method2 end end # (4) 特異クラスのコンテキストで実行するための記法 <<obj を利用 # オブジェクトA の特異クラスをオープンしている。 # クラスであるオブジェクトA の特異クラスにメソッドを定義している。 # Ruby では特異クラスのメソッド = 特異メソッドで、 # クラスの特異メソッド = クラスメソッドなのでこれはクラスメソッドになる class <<A def class_method2 end end # (5) instance_eval の中でメソッド定義 # instance_eval の中で def ... end を書くと、レシーバ # オブジェクトの特異クラスにメソッド定義される # A はクラスなので、これはクラスメソッドになる A.instance_eval do def class_method1 end end class A def initialize # (6) 通常のインスタンスメソッドの定義 # クラスのコンテキストなので、インスタンスメソッドが定義される def instance_method3 end # (7) クラスのコンテキストから、instance_eval を実行して特異メソッドを定義 # オブジェクトの特異クラスにメソッドが定義されるため、 # シングルトンメソッドが定義される self.instance_eval do def singleton_method1 end end end end # (8) トップレベルから instance_eval で特異クラスにメソッドを定義 a = A.new a.instance_eval do def singleton_method2 end end # (9) オブジェクトを指定したメソッド定義 # 指定したオブジエクトの特異クラスにメソッド定義される # 特異メソッド定義中でもカレントクラスは変更されないため、 # トップレベルのメソツドになる。 def a.singleton_method3 def toplevel_method2 end end a.singleton_method3 p a.singleton_methods p A.instance_methods - methods p A.singleton_methods
2010-07-04 [プログラミング] LiveCoding で 解説
■[プログラミング] LiveCoding で 解説 
cuzic です。
もう先週のことですが、LiveCoding#10 に参加してきたら、突然 解説を依頼され、解説してきました。
イベント内容は、yhara さんと nari さんのすごいギークがコーディングするのをみんなで見よう!みたいなもので、最近は sixeight さんが中心に非常に熱気を持って実施されています。
LiveCoding#10 では「プロの変な言語作者」yhara さんと、「日本のガーベッジコレクション界の権威」 nari さんが最強タッグを組んで、新しい言語をわずか40分で実装するというものでした。
yhara さんの整数や文字列を含めてすべてを配列で表現するという新言語にはちょっとドギモを抜かれました。
変な言語にはいろいろとありますが、そこまで限定をするという発想にはびっくりしました。
40分時間があるとはいえ、ちゃんとテストを書きながらコードを書いていた点も感銘を受けました。自分のスタイルへのこだわりを感じます。
ガーベージコレクションについては基本的な原理などは一通り勉強したことはあるものの、実際のコードについては、ちゃんと見て勉強したことなどはあまりなかったので、今回の企画のようにコンパクトなガーベッジコレクション実装を実際に作成しているところを見ることができたのは、大変勉強になりました。
私の解説についてですが、突然の依頼で準備が足りず、聞き苦しかった部分もあったかと思うのですが、多くの方から好評いただいていたようで、よかったです。
2010-06-22 [プログラミング] Ruby でクラス定義の DSL 作成
■[プログラミング] Ruby でクラス定義の DSL 作成 
cuzic です。
今日も Ruby の話題です。
理由はないのですが、大林さんの昔出した課題のような問題に取り組んでみました。
目標は、
A = AttrClass :accessor, :with_default => 1 do
def initialize
puts "initialized"
end
def do_something
puts "do_something"
end
end
a = A.new #=> intialized
p a.accessor #=> nil
a.accessor = "some value"
p a.accessor #=> "some value"
p a.with_default #=> 1
a.with_default = 2
p a.with_default #=> 2
a.do_something #=> do_something
となるような AttrClass メソッドを定義することです。
つまり、AttrClass メソッドの呼び出しが下記のコードと等価になるようにする、ということです。
class A attr_accessor :accessor attr_accessor :with_default def initialize @with_default = 1 puts "initialized" end def do_something puts "do_something" end end
これはやってみると、比較的簡単にできました。
次のようなメソッド定義になります。
def AttrClass *symbols, &block Class.new do |klass| symbols.each do |sym| case sym when Symbol attr_accessor sym when Hash klass.class_eval do sym.each do |key, value| attr_accessor key end end Module.new do new_original = klass.method :new define_method :new do |*args, &block| obj = new_original.call *args, &block sym.each do |key, value| obj.__send__ "#{key}=", value end obj end extend_object klass end end end klass.class_eval &block klass end end
ポイントは、Class#class_eval を使って、Class のコンテキストでブロックを評価していることや、new クラスメソツドを再定義して、インスタンス変数の初期化を行っているところでしょうか。
これを使えば、アクセサなどが多いクラス定義がより簡潔に書けます。
2010-06-21 [プログラミング] Rubyのドキュメンテーション YARD編 (1)
■[プログラミング] Rubyのドキュメンテーション YARD編 (1) 
cuzic です。
WMI でいろいろとプロパティなどを観察していて、Description という Qualifier でその WMI クラスのプロパティに関する詳細な説明が得られることに気がつきました。
簡単な例としては、
require 'win32ole'
loc = WIN32OLE.new("WbemScripting.SWbemLocator")
service = loc.ConnectServer
service.SubclassesOf("", 131072).each do |klass|
desc = klass.Qualifiers_.Item("Description") rescue nil
puts "#{klass.Name} #{desc}\n" if desc
end
とすると、さまざまな WMI クラスの説明を表示できます。131072 (= 0x20_000)
プロパティ、メソッド、メソッドの引数などについて、Description の Qualifier が設定されているため、ドキュメントとして、十分な情報が得られます。
そこで、Ruby のドキュメント作成方法について学ぶための題材として WMI の Description の Qualifier が使うというアイデアを思いついてみました。
まずは、Ruby のリファレンスマニュアルとして使われている bitclust を利用して、ドキュメントの作成を検討してみたのですが、どうも標準ライブラリが前提からなのか、やり方がよく分かりませんでした。
次に、Ruby でよく使われているドキュメント作成ツールである RDoc を採用しようと思ったのですが、パラメータ引数の説明の書き方などがよく分からなかったり、attr_reader とかと、メソッド定義をいい感じに区別して表示させたかったのですが、やり方を見つけられませんでした。
次に試したのは、RDoc の後継(?)の YARD です。YARD を使うとやりたいことが一通りできそうな上、書き方が私にとって、すんなり理解できたのですぐに気に入りました。
## # Caption プロパティは、オブジェクトについての簡単な説明 (1 行分の文字列) です。 # @return [string] Caption attr_reader :Caption
のように、@return や、@param のような JavaDoc の書き方は見慣れていて、すんなりついていけます。
そこで、YARD を使って WMI のドキュメントを作成してみました。ここにおいてみています。
YARD を使ってみて、思ったことは、
- デフォルトの色合いとかはけっこうそつがないかんじで、見やすい
- カスタマイズは柔軟そう。ドキュメントもいろいろと書かれていて、探求する価値がありそうです。
- 生成がとても遅い。今回はかなりの分量があったせいかもしれませんが10分以上かかってびっくりしました。
といったところです。
YARDは拡張性やカスタマイズが容易そうな印象なので、そのあたりについても探求していきたいな、と思いました。
http://www.dartlang.org/docs/spec/dartLangSpec.pdf