Self-modifying code in Ruby

左心房为你撑大大i 提交于 2019-12-24 15:11:40

问题


I am concerned about writing self-modifying code in Ruby. And by self-modifying, I mean being able to write functions that take a code block as an input value, and output another code block based on this. (I am not asking about basics such as redefining methods at runtime.)

What I might want to do is, for example, having the following block,

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

one can notice that arguments a and d are not used in the body at all, so I would like a function eg. #strip to remove them,

x = _x_.strip

which should produce same result as writing:

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

Now in Lisp, this would be easy, since Lisp code is easily manipulable data. But I do not know how to manipulate Ruby code. I can parse it eg. by

RubyVM::InstructionSequence.disassemble( x )

But how, based on this, do I write a modified block? Other examples of what I would want to do are are eg.

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

So far, in Ruby, I have never encountered a situation where I had to concede that something is not possible. But this time, gut feeling tells me that I might have encountered the fundamental weakness of beautifully structured code vs. code with little syntax to speak about (which would be Lisp). Please enlighten me.


回答1:


Boris do you necessarily have to rely on Ruby to begin with here?

Why not just create your own situation-specific language that the chemists can use just for the purpose to express their formulas in the most convenient way. Then you create a simple parser and compiler for this "chemical expression language".

What I mean is this parser and compiler will parse and compile the expressions the chemists write in their Ruby code. Then you could have:

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

Voila: ultimate flexibility.

That's the approach I would take if usability is your main concern. Already writing out "lambda" seems like an unnecessarily cumbersome thing to me here, if all you want to do is express some domain-specific formula in the most compact way possible.




回答2:


Detecting whether a block variable is used or not is a complicated task, and you seem to be saying that you can do that by using RubyVM. So the question seems to be asking how to change the arity of the code.

If you have:

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

and suppose you were able to use RubyVM and come to know that a and d are not used, so you want to create

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

out of _x_. Then, that is simple:

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


来源:https://stackoverflow.com/questions/14658230/self-modifying-code-in-ruby

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!