簡単な算術演算用に小さな DSL を Ruby で書きたいと思っています。次のようになります。
whats 1 + 1
=> 2
whats 2 * 2
=> 4
ユースケースは、子供にプログラミングを教えることです。私は彼女に を使った基本的なプログラミングを見せていましirb
た。私が彼女にキーボードを渡すと、彼女は「whats 2 + 2」と入力しました。Ruby では可能ですか?
実際には、それは非常に簡単です:
def whats expr; expr end
whats 1 + 1
# => 2
Ruby の演算子の優先順位のせいで、あなたが望んでいることをそれほどエレガントに行うことはできません。つまり、は(and )whats 1 + 1
と同じであるため、メソッドはその引数で操作が発生したことを知りません。whats(1 + 1)
whats(2)
whats
Fixnum#+
ある種のビルダー オブジェクトを返すには、(およびその他の演算子を)オーバーライドする必要があります。例えば:
MathQuery = Struct.new(:left, :operator, :right)
class Fixnum
def + other
MathQuery.new(self, :+, other)
end
end
次に1 + 1
、MathQuery インスタンスを返します。このインスタンスは、whats
処理方法を受け取り、認識します。
もちろん、これに関する問題は、多くのコードが明らかに期待しているため、何らかの方法で通常の数学演算も機能させる必要があることです。ただし、それをどのようにやってのけるかはよくわかりません。たぶん、すべてが常にto_int
などで強制されていれば…</p>
その場合、Treetopのようなものを使用して実際のミニ言語とパーサーを作成する方がよい場合があります。
「whats」というメソッドを作成し、任意の数の引数を受け入れ、演算子部分に一致させて続行します。