Чтобы ответить на ваш последний вопрос первым, eval (во всех его вариациях) полностью отличается от exec. exec $command
запустит новый процесс, чтобы запустить указанную вами команду, а затем завершится после ее завершения.
class_eval
и module_eval
имеют право переопределять классы и модули - даже те, которые вы сами не написали. Например, вы можете использовать класс eval для добавления нового несуществующего метода.
Fixnum.class_eval { def number; self; end }
7.number # returns '7'
class_eval
можно использовать для добавления методов экземпляра, а instance_eval
можно использовать для добавления методов класса (да, эта часть очень запутанная). Метод класса будет выглядеть примерно так: Thing.foo
- вы буквально вызываете метод foo
в классе Thing
. Метод экземпляра похож на пример выше, используя class_eval
Я добавил number
метод к каждому экземпляру Fixnum
.
Хорошо, это класс методов *_eval
. Методы exec похожи, но они позволяют вам заглянуть внутрь класса и выполнить блок кода, как если бы он был определен как метод для этого класса. Возможно, у вас есть класс, который выглядит так:
class Foo
@@secret = 'secret key'
@@protected = 'some secret value'
def protected(key)
if key == @@secret
return @@protected
end
end
end
Класс Foo
- это просто обертка вокруг некоторого секретного значения, если вы знаете правильный ключ. Тем не менее, вы можете обмануть класс и дать ему его секреты, выполнив блок внутри контекста класса следующим образом:
Foo.class_exec { @@secret = 'i'm a hacker' }
Foo.protected('i'm a hacker') #returns the value of @@protected because we overwrote @@secret
В общем, с большим количеством инструментов в ruby, вы можете использовать любой из них, чтобы решить множество проблем. Большую часть времени вам, вероятно, даже не понадобится, если вы не хотите «обезьянить» патчить класс, который определила определенная вами библиотека (хотя это открывает целую банку червей). Попробуйте поиграть с ними в irb и посмотрите, что вам проще. Лично я не использую методы *_exec
так часто, как методы *_eval
, но это мое личное предпочтение.