4 ms·
Why Rails' magic and DSL style might not be good
- tjogin 17y agoI 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 17y agoOf 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.
- jcapote 17y agoIf your "framework" is only meant to run a single custom application...it's not much of a framework
- tptacek 17y agoI'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 17y agoIt wasn't really intended as a security example, more another example of unintended things happening if you don't know all the rules.
- donw 17y agoThe 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 17y agoIt 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.
- tptacek 17y agoIf you don't understand the difference between "public" and "private" methods, no amount of object orientation is going to help you. Note also that Rails isn't even close to the first environment to use public scope to export methods.
- technoweenie 17y agoRails has a more explicit method for hiding controller methods: hide_action. It sounds like the author wants to add methods explicitly instead. You could also use routes for this. I never use the default ':controller/:action/:id' route in my apps. It could get around the issue of having methods that clash with Object. #profile is a hilarious one, don't try it :) Anyways, the author makes some valid points I suppose. One suggestion to make #layout more obvious would be using ruby Method objects: layout "foo" # loads 'layouts/foo.html.erb' layout instance_method(:foo) # calls #foo to get the layout string EDIT: I'm not really serious with this suggestion -- but I can see how the difference between a string and a symbol could get confusing. Fortunately, this topic is documented pretty well too: http://rails.rubyonrails.org/classes/ActionController/Layout/ClassMethods.html#M000468 http://rails.rubyonrails.org/classes/ActionController/Layout...
- richcollins 17y agoI 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.
- deleted 17y ago[deleted]
- bensummers 17y agoObjective-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.
- sorbits 17y agoDSLs 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/ http://www.complang.org/ragel/
- bensummers 17y agoHaving 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.
- ianbishop 17y ago'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?
- deleted 17y ago[deleted]
- betageek 17y agovalid point if 'use the right tool for the job' is a valid point? very misguided examples for anyone that's used Rails extensively