Меня беспокоит написание самомодифицирующегося кода на Ruby. И под самоизменением я имею в виду возможность писать функции, которые принимают блок кода в качестве входного значения и выводят другой блок кода на основе этого. (Я не спрашиваю об основах, таких как переопределение методов во время выполнения.)
То, что я мог бы сделать, это, например, иметь следующий блок,
_x_ = lambda { |a, b, c, d| b + c }
можно заметить, что аргументы a
и d
вообще не используются в теле, поэтому я хотел бы, чтобы функция, например. #strip
чтобы удалить их,
x = _x_.strip
который должен дать тот же результат, что и запись:
x = lambda { |b, c| b + c }
Теперь в Лиспе это было бы легко, поскольку код Лиспа — это данные, которыми легко манипулировать. Но я не знаю, как манипулировать кодом Ruby. Я могу разобрать его, например. от
RubyVM::InstructionSequence.disassemble( x )
Но как, исходя из этого, написать измененный блок? Другими примерами того, что я хотел бы сделать, являются, например.
y = lambda { A + B }
y.deconstantize
# should give block same as saying
lambda { |_A, _B| _A + _B }
До сих пор в Ruby я ни разу не сталкивался с ситуацией, когда мне приходилось признать, что что-то невозможно. Но на этот раз интуиция подсказывает мне, что я, возможно, столкнулся с фундаментальной слабостью красиво структурированного кода по сравнению с кодом с небольшим синтаксисом, о котором можно было бы говорить (которым был бы Лисп). Пожалуйста, просветите меня.
ChemicalReaction.new( name: "A_and_B_assembly", rate: proc { A * B * 0.189 } )
. Я хочу облегчить задачу пользователю, поэтому я не хочу, чтобы он писалproc { |_A, _B| _A * _B * 0.189 }
, что это и будет означать (0,189 - константа скорости)... - person Boris Stitnicky   schedule 02.02.2013instance_eval
и друзей? В конечном итоге вы можете сказать{ @a * @b * 0.189 }
, но вы, вероятно, могли бы обойти это с помощью методовa
иb
, не так ли? - person mu is too short   schedule 02.02.2013ATP
,Adenosine
,DeoxyCytidine
. Затем я написал фальшивую константную магию, которая позволяет мне писатьATP = Chemical Species.new
. А теперь из технического интереса или упрямства я считаю некрасивым писатьrate: lambda { _ATP * _GDP * NDPK_constant }
. Я хочу быть особенным, разрешивlambda { ATP * GDP * NDPK_constant }
или хотя быlambda { [ATP] * [GDP] * NDPK_constant }
, как это делают химики, чего бы это ни стоило. Как вы должны знать, константы, написанные с заглавной буквы, фиксируются в блоках по-разному. - person Boris Stitnicky   schedule 02.02.2013