Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby performance: define method with define_method or eval

While looking through ActiveSupport source code I've noticed that sometimes eval is used in places where define_method is enough.

Example: ActiveSupport: Module.delegate

I consider define_method more clean and safe way of doing things. What is the benefits of eval over define_method? Perfomance, memory usage, something else?

like image 817
Bogdan Gusiev Avatar asked Jul 04 '11 07:07

Bogdan Gusiev


3 Answers

When you use define_method, the method you're defining can't accept a block.

It’s pretty well known that because of a deficiency in blocks arguments in Ruby 1.8 Class#define_method cannot define methods that take blocks.

def x *args, █ end  # => works!
define_method(:x) {|*args,&block| } # => SyntaxError: compile error

The method being defined requires a block:

"def #{prefix}#{method}(*args, &block)" # def customer_name(*args, &block)

So define_method can't be used.

like image 190
Andrew Grimm Avatar answered Nov 20 '22 18:11

Andrew Grimm


I found this to be a very nice article on the subject: http://blog.grayproductions.net/articles/eval_isnt_quite_pure_evil.

like image 28
emboss Avatar answered Nov 20 '22 19:11

emboss


I don't know what the reason in that particular case, but define_method takes a block, which is a closure (carries local variables of the place it was defined), and that can lead to considerably higher memory consumption comparing to plain eval.

like image 28
Victor Deryagin Avatar answered Nov 20 '22 19:11

Victor Deryagin