Rubyな日々

最近あまりにブログを書いてないのでRubyネタを2つほど
強い.zero?Lisp in Ruby

強い.zero?

https://gist.github.com/tompng/5031911
RubyにあるFixnum#zero?メソッドを強くしてみました。

出来る事

.zero?以外に.one? .two?とかが使えます。

  30.thirty?
  1000.thousand?
  -102.5.minusonehundredtwopointfive?

0 1 2...の代わりにzero one two...を使えます

ten.times do |i|
  print "----" if i.five?
  p i*threepointonefour
end

コード中の数値を全て英語表記に変えれちゃいます。誰得

仕組み

method_missingメソッドを定義しておくと、
存在しないメソッドを呼んだ時にゴニョゴニョできます

def method_missing name,*args
  if name.to_s.match /say_(.+)/
    print "hello #{$1}!\n"
  else
    super
  end
end
say_world
=> hello world!
say_goodbye
=> hello goodbye!

Lisp in Ruby

https://github.com/tompng/rubyhogelisp

(hoge (piyo (fuga 3),(foo 4,5)),(bar 5))

このLispっぽい表記がRubyだと構文エラーにならない。
じゃあいっそLisp動かしちゃおう、と思って。

結果
Lisp do (car (cons (cons 1,(list 2,3,4)),5)) end
=> (1, 2, 3, 4)
Lisp do
  (progn\
    (define (fact :n),
      (ifelse (eq :n,0),
        1,(mult :n,(fact (sub :n,1))))),
    (fact 5)
  )
end
=> 120
Rubyのいろんなgemの機能も一応使えます
require 'sinatra'
Lisp do
  (let :count,0,
    (call (get '/'),
      (progn\
        (set :count,(add :count,1)),
        (set :cntstr,(send :count,(to_s))),
        (call (system 'say',:cntstr)),
        (add (send (call params),(to_s)),:cntstr)
      )
    )
  )
end
=> sinatraが動く!
仕組み

これまたmethod_missing使って怪しい事してます。
まずdo-end内のLispっぽい式全体を実行して構文木を取り出す。
(実行するだけで構文木が構築されるようにmethod_missingをいじってます)
その先は力技でLispっぽいインタプリタを書いて動かす。以上!