1

Ruby での自己変更コードの記述について懸念があります。自己変更とは、コード ブロックを入力値として受け取り、これに基づいて別のコード ブロックを出力する関数を記述できることを意味します。(実行時にメソッドを再定義するなどの基本については質問していません。)

私がやりたいことは、たとえば、次のブロックを持つことです。

_x_ = lambda { |a, b, c, d| b + c }

a引数とdが本体でまったく使用されていないことに気付くことができるので、たとえば関数が必要です。#stripそれらを削除するには、

x = _x_.strip

次のように記述した場合と同じ結果が得られるはずです。

x = lambda { |b, c| b + c }

Lisp では、Lisp コードは簡単に操作できるデータであるため、これは簡単です。しかし、Ruby コードの操作方法がわかりません。私はそれを解析することができます。に

RubyVM::InstructionSequence.disassemble( x )

しかし、これに基づいて、変更されたブロックをどのように書くのでしょうか? 私がやりたいことの他の例は、例えばです。

y = lambda { A + B }
y.deconstantize
# should give block same as saying
lambda { |_A, _B| _A + _B }

これまでのところ、Ruby では、何かが不可能であることを認めなければならない状況に遭遇したことはありません。しかし今回は、直感的に、美しく構造化されたコードと、話す構文がほとんどないコード (Lisp など) の根本的な弱点に遭遇した可能性があることを教えてくれます。教えてください。

4

2 に答える 2

2

ブロック変数が使用されているかどうかを検出するのは複雑な作業であり、 を使用するとそれができるとおっしゃっているようですRubyVM。したがって、問題はコードのアリティを変更する方法を尋ねているようです。

あなたが持っている場合:

_x_ = ->a, b, c, d{b + c}

RubyVMそして、あなたがそれを使うことができてそれを知るようになり、使われaていないと仮定すると、あなたはd作成したいと思います

x = ->b, c{b + c}

のうち_x_。次に、それは簡単です:

x = ->b, c{_x_.call(nil, b, c, nil)}
于 2013-02-02T03:25:21.580 に答える
1

Borisは、ここから始めるために、必ずしもRubyに依存する必要がありますか?

化学者が最も便利な方法で数式を表現する目的でのみ使用できる、独自の状況固有の言語を作成してみませんか。次に、この「化学式言語」用の単純なパーサーとコンパイラーを作成します。

つまり、このパーサーとコンパイラーは、化学者がRubyコードに書き込んだ式を解析してコンパイルします。次に、次のことができます。

ChemicalReaction.new(..., "[ATP] * [GDP] * NDPK_constant")

出来上がり:究極の柔軟性。

それが、ユーザビリティがあなたの主な関心事である場合に私がとるアプローチです。すでに「ラムダ」を書き出すことは、ここで私には不必要に面倒なことのように思えます。もしあなたがしたいのが、可能な限り最もコンパクトな方法でドメイン固有の式を表現することだけなら。

于 2013-02-02T05:07:43.607 に答える