2013-02-02 48 views
1

我很擔心在Ruby中編寫自修改代碼。而通過自我修改,我的意思是能夠編寫以代碼塊爲輸入值的函數,並基於此輸出另一個代碼塊。 (我不是問基礎知識,如在運行時重新定義方法。)Ruby中的自修改代碼

我可能想要做的是,例如,具有以下塊,

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

可以注意到參數ad根本沒有在身體中使用,所以我想要一個功能,例如。 #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)。請賜教。

+0

你有這方面的具體用例嗎? – Nevir

+0

要檢測未使用的變量,您將不得不下降到AST級別;可能通過[墨爾本寶石](https://github.com/simplabs/melbourne)。然而,有可能有一種不同的/更方便的方法來覆蓋你的用例 – Nevir

+0

@Nevir:但我確實是這樣做的。我不是旅遊者,我不會去我無所事事的地方:-)。想象下面的代碼:'ChemicalReaction.new(name:「A_and_B_assembly」,rate:proc {A * B * 0.189})'。我想在用戶面前輕鬆一些,所以我不希望他們寫'proc {| _A,_B | _A * _B * 0.189}'這就是這意味着什麼(0.189是速率常數)...... –

回答

1

鮑里斯你一定要依靠Ruby來從這裏開始?

爲什麼不建立自己的情境特定語言,化學家只能用它來以最便捷的方式表達他們的公式。然後你爲這個「化學表達式語言」創建一個簡單的解析器和編譯器。

我的意思是說這個解析器和編譯器會解析和編譯化學家在他們的Ruby代碼中寫入的表達式。那麼你可以有:

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

Voila:最終的靈活性。

如果可用性是您最關心的問題,那麼我會採用這種方法。已經寫出「lambda」對我來說似乎是一件不必要的麻煩事,如果你只想用最簡潔的方式表達一些特定於領域的公式。

+0

我非常感謝你的回答,它演示了mongers稱之爲在盒子外面思考的詞組。但相信我,卡斯帕,我已經看到足以確定Ruby DSL是我想要的。丹伯恩斯坦的說法是,不要解析。我不想解析。我想要使​​用Ruby解析器。正如你所看到的,我已經有了不完美的解決方案:使用與chem的常量名稱有關的變量名稱。塊之外的物種,以及'instance_eval'塊在正確的環境中。但這並非完全完美。所以我希望通過問全能SO來學習更多。 –

+0

@BorisStitnicky好吧,這很酷。感謝您的評論。我很佩服你的韌性:)我喜歡爲這樣的情況編寫解析器,但是如果你能在Ruby中使用它,那麼我承認它更好。 – Casper

+0

編輯後再次閱讀您的答案,如果沒有人提供更好的答案,我會接受你的答案。你對這裏的琴絃是正確的。我只是莫名其妙地......我想我正在遭受一種對Lisp羨慕的功能:-) –

2

檢測塊變量是否被使用是一項複雜的任務,您似乎在說可以使用RubyVM來做到這一點。所以這個問題似乎在問如何改變代碼的秩序。

如果您有:

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

,並假設你能夠使用RubyVM和來知道ad都沒有用,所以你需要創建

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

_x_ 。然後,這很簡單:

x = ->b, c{_x_.call(nil, b, c, nil)} 
+0

O.K.,我必須說我涉及到arity變化的例子並不是最好的,因爲它有時可以用'#curry'方法來解決,而這並不是我所追求的。我很誠實,Lisp喜歡自我修改。 –

+0

等等,現在我讀了你的答案......你知道,我在線上談話時並不經常使用所有的資本,但是當你可以通過硬編碼一個不同的代碼來修改代碼時。我在問什麼是自我修改代碼。那個「自己」不是程序員,而是程序「本身」。現在,我感受到斯坦萊姆的新嘗試,以解釋他的自動化他只是使2 + 2不是5,但是4. –

+1

鮑里斯,我覺得你的問題有趣和有用,但請不要輸入全部大寫,因爲它不會輸入無論如何,這無助於對話。 – sunnyrjuneja