On 07.12.2012 16:23, Rodrigo Rosenfeld Rosas wrote:
> Not all column names can be represented as method names. Or can they?

Most columns should be possible, considering that even unicode method 
names are valid.

For those cases where it's not possible there is __send__ in 
BasicObject. Or you can manually generate the AST-Object that would 
normally be spawned by method_missing. Or you could have a custom helper 
method. Or you could just call method_missing directly.

And before you say that's ugly, compare the following:

a)

   Foo.query{__send__("`illegal_method_name") == bar}


b)
   using SomeDSLRefinement do
     Foo.query(:"`illegal_symbol_name" => :bar)
   end


Personally I consider the first one more elegant, concise and 
expressive. Especially since you can actually write ruby code in the 
block and thus do things dynamically.

> Even if they could I don't like this approach. Look, I currently
> maintain an application that has some parts written in Grails, others in
> plain Java and others in Rails. I can do things even more advanced than
> what you suggested in Grails thanks to some features in Groovy.
>
> But the problem begins when you have some local variable (or method)
> name that happens to be the same as the column.

Local methods are not a problem with an instance_eval'd block on 
BasicObject. Local variables may conflict, but you have control over 
them since they are by definition *local*.


> In such cases the DSL approach doesn't really help and may yield to
> unexpected results (from a user POV)

Those "problems" are far more benign than the havok sometimes caused by 
monkey patching and usually result from a lack of understanding of the 
employed metaprogramming methods. I.e. it's a problem that can be fixed 
simply by increasing the user's knowledge through good documentation.



So really, i find this approach to making DSLs much cleaner than 
patching around in core objects.

Of course monkey patching does have its place, I'm not going to deny 
that. But DSLs shouldn't be the primary use-case for it. Glueing 
together two libraries that don't interact nicely with each other or or 
providing widely used utility methods throughout a whole gem/application 
namespace would be far more important in my opinion.