2014-04-01から1ヶ月間の記事一覧

Ruby/GTK のレイアウトを作るための DSL を作った

こんなのは DSL って言わないかもしれないけれど、ウィジェットの親子関係がインデントで表せてわかりやすいです。あと、名前付きオプション引数でウィジェットのプロパティが設定できたり、シグナル名を書くだけで convention で名前が付いてコールバックが…

続・Ruby で labels できるか

先日、Ruby で labels に類似したパターンを書いたが、見た目も labels にできた。まずは実例から。例によって階乗。 def fact(n) labels iter: -> m, acc { m==0 ? acc : iter(m-1, m*acc) } do iter(n, 1) end end fact(10) => 3628800 実装は次のようにな…

Ruby で labels できるか

次のコードに等価なものを作りたい。 (defun f (a b) (labels ((g (c) (list a b c))) (g 'z))) (f 'x 'y) ; => (X Y Z) 新しい Object にシングルトンメソッドを定義しよう。 def f a, b Object.new.instance_eval { self.define_singleton_method(:g) do |…

do end で引数リストにカッコを付けてはいけない謎の文法環境

Ruby ではメソッドに渡すブロックの表記に do end と {} の2つがあるが、その違いの一つは、do end は引数リストの括弧を省略できるということだ。次のようなテスト用のメソッドを用意して、確かめてみる。 # 渡された引数とブロック引数を配列にして返す。…

S式を1つ読み飛ばすリードマクロを作ってみた

HTML のように閉じ括弧にコメントをつけられるよ。 ;; 3の倍数か? (def mult_three? (n) (if (.== 0 (.% n 3)) true false #/if) #/def)

やっぱりメソッド呼び出しを . で始めるようにした

関数位置に置けるのは、関数を表すシンボルと lambda フォーム、proc フォーム、そして meth フォーム。. は meth フォームを生成するリードマクロだ。 ラムダ > ((lambda (x) (.* x 2)) 3) read: [[:lambda, [:x], [[:meth, :*], :x, 2]], 3] ruby: lambda …

続・tapの「使え方」

逆に露骨に副作用を起こすこともできる。 i = 0 i.tap { i += 1 } 2行目の式は 0 に評価され、副作用として i が 1 になる。ちょうどC言語の後置インクリメント演算子のようだ*1。tap のレシーバが評価されるのが(tap 内部で行われる)ブロックの呼び出し…

tap の「使え方」

tap に渡すブロックで break をするとその break が tap の返り値を決定する。例えば、true.tap { break false } は false になる。さて、以下の関数は、数当てゲームのヌメロンでプレーヤーの推測と答えを比較して、イート数(位置も数もあっている)とバイ…

普通の tap の使い方

tap is a method for eavesdropping on any portion of an expression.Suppose there is a bug in the following code: data.foo.bar.baz It could be that data is not what you expect it to be, or one (or more) of the methods foo, bar and baz doesn'…

Lisp on Ruby に ’ と let と gensym を実装した

quote はあったがリードマクロの ' がなかったので実装した。とは言っても、本当のリードマクロのように関数に処理がディスパッチされるわけではなくて、組み込みだ。前回、rotatef を次のように定義した。 (defmacro rotatef (a b) (.list (quote progn) (.…

Ruby の上に Lisp っぽいものを作ってみた。

足し算ができる。 > (+ 10 20) 30 式の実態は Array クラスのオブジェクトとシンボルなどだ。 > (quote (+ 10 20)) [:+, 10, 20] Ruby のコードにコンパイルされてから実行される。 > (compile_sexp RubyLisp (quote (+ 10 20))) "10.+(20)" グローバル関数…

Ubuntu の DNS キャッシュ

ネットワークのパフォーマンス測定みたいなことをやっていたら、たびたびドメイン名の解決が遅いことに気がついた。システムは localhost に問い合わせているのは知っていたので、何が動いているのだろうと調べてみると、dnsmasq というのが走っていた。ネッ…