

Why Rails' magic and DSL style might not be good - bensummers
http://bens.me.uk/2009/going-off-the-rails

======
tptacek
I've got no opinion on the difference between the "layout" classmethod and the
"determine_layout" overridden object method, but his security example is ass-
backwards: every other framework with a more "explicit" mechanism for
exporting/hiding methods has produced applications riddled with authorization
bugs. J2EE is a great example.

You don't make a strong case for the evils of "Rails magic" by pointing out
that bad things happen when you leave off the "private" declaration in a class
definition.

~~~
bensummers
It wasn't really intended as a security example, more another example of
unintended things happening if you don't know all the rules.

~~~
donw
The rules in this case seem pretty standard to me; public/private methods work
the same in controllers as they do in every other object. Rails is just using
an existing mechanism that's been around in OO languages for a very, very long
time, rather than implementing something else that does the exact same thing.

~~~
bensummers
It is reusing a standard OO mechanism, just not as well as it could. If all
the Rails security tutorials feel they have to mention this point, then it's
an indication that the design isn't quite right.

------
sorbits
DSLs are great when they bring the code closer to being a description of the
problem / logic / assertions. One example of a highly successful embedded DSL
is regular expressions.

A DSLs made by using a language’s features for operator overloading, magic
constants, and similar, has the advantage that the “code” in the DSL is part
of the original source, but it also has the big disadvantage that it tends to
show many compromises due to limits of the host language, so the syntax will
be arcane and non-standard.

Though this isn’t specific to Ruby/Rails. I think the problem is twofold, 1)
the advantage of having the DSL embedded and 2) the advantage (for the creator
of the DSL) of not having to build an actual compiler for the DSL.

Something like Ragel¹ solves #1 by being a preprocessor.

¹ <http://www.complang.org/ragel/>

~~~
bensummers
Having implemented a web app framework using a preprocessor, I found it was a
bit of a pain to write and use. So using the language features makes sense to
get the job done.

But I was trying to question whether or not a DSL was the right way to go for
a web app. If you use as many of the standard features and keywords as
possible, there's no ambiguity over what a special keyword means.

------
tjogin
I don't understand why he's calling any of that "magic". There's nothing magic
about it, not even a little bit. He doesn't comprehend how the libraries he is
using actually works internally, and that is all there is to it.

Is this what passes for "magic" now? Simply not understanding, or caring
about, how the libraries you use work internally? That's "magic"?

~~~
bensummers
Of course there's nothing actually magic about it, because you can read the
source. As with any large system, it's quite impenetrable in places, but I do
suspect some of the design choices have made it more complex than it could be.

Trying to make a "literate" DSL which reads as much like English as possible
means using it can become subtly surprising, as well as complicating the
framework implementation. I am questioning the trade-off of terse readable
code vs slightly more verbose code which is still readable but uses
predictable language features.

That said, I like Rails, and it works very well for the things it's designed
to do.

------
richcollins
I agree with the layout example and would add that prototype based languages
that unify method calls with attribute lookups (through message sends) give
you both:

    
    
      SomeController := Controller clone do(
        layout := "template"
      )
    
      SomeController := Controller clone do(
        layout := method(
            if(params at("foo") == "bar", "foo-template", "template")
        )
      )
    

This way the framework would send the layout message to the cloned
SomeController object and get the proper layout name for either case.

~~~
bensummers
Objective-C 2 could be quite nice for this too. It's a nice mix between static
and dynamic languages, and a function of this nature can be implemented as a
property or as a receiver of a message.

------
ianbishop
'For example, the View code is executed in a different context to the
Controller, yet the @instance variables are magically available, along with
the magically included helper modules.'

What - what? How is this magic? How else could this possibly be implemented
without breaking MVC?

------
jcapote
If your "framework" is only meant to run a single custom application...it's
not much of a framework

------
betageek
valid point if 'use the right tool for the job' is a valid point? very
misguided examples for anyone that's used Rails extensively

