Я иногда, хотя очень редко делаю самоизменяющийся код в Ruby.
Иногда у вас есть метод, в котором вы на самом деле не знаете, правильно ли инициализируются используемые вами данные (например, ленивый кеш) или нет. Итак, вы должны проверить в начале вашего метода, правильно ли инициализированы данные, а затем, возможно, инициализировать их. Но вам действительно нужно выполнить эту инициализацию только один раз, но вы проверяете ее каждый раз.
Итак, иногда я пишу метод, который выполняет инициализацию, а затем заменяет себя версией, не содержащей код инициализации.
class Cache
def [](key)
@backing_store ||= self.expensive_initialization
def [](key)
@backing_store[key]
end
@backing_store[key]
end
end
Но, честно говоря, я не думаю, что это того стоит. На самом деле, мне стыдно признать, что я никогда не проводил сравнительный анализ, чтобы понять, действительно ли это условное условие 1010 * one имеет какое-либо значение. (В современной реализации Ruby с агрессивно оптимизирующим JIT-компилятором, управляемым обратной связью, вероятно, нет.)
Обратите внимание, что в зависимости от того, как вы определяете"самоизменяющийся код", это может быть, а может и не быть тем, что вы хотите. Вы заменяете часть выполняемой в данный момент программы, поэтому & hellip;
РЕДАКТИРОВАТЬ: Теперь, когда я думаю об этом, оптимизация не имеет особого смысла. В любом случае дорогая инициализация выполняется только один раз. Единственное, чего избегает модификация, это условно. Было бы лучше взять пример, где сам чек стоит дорого, но я не могу вспомнить ни одного.
Однако я подумал о замечательном примере самоизменяющегося кода: Maxine JVM . Maxine - это исследовательская виртуальная машина (технически не разрешено называть «JVM», поскольку ее разработчики не запускают тесты совместимости), полностью написанные на Java. Теперь, есть много JVM, написанных сами по себе, но Максин - единственная, о которой я знаю, что запускает сама по себе. Это очень сильно. Например, JIT-компилятор может JIT-компилировать себя, чтобы адаптировать его к типу кода, который JIT-компилирует.
Очень похожая вещь происходит в Klein VM , которая является виртуальной машиной для языка самопрограммирования.
В обоих случаях виртуальная машина может оптимизировать и перекомпилировать сама во время выполнения.