5 ms·
That is so far from anything I would ever want to see on a slide (unless it's just meant to poke fun at such code), I don't even know where to begin. When you
by leif 17y ago
That is so far from anything I would ever want to see on a slide (unless it's just meant to poke fun at such code), I don't even know where to begin.
When you program, do you think of it as an exercise in bending your mind to the whim of the computer, or the other way around? I, for one, would rather make the computer understand what I'm thinking.
If I'm thinking "hey, I want to evaluate this bit a bunch of times with different names", why can't I just say that? Isn't Ruby supposed to be the "English With Some Bits Of Punctuation" language? Assuming I've met any security concerns, and I'm not doing anything incredibly complicated (which, honestly, wouldn't pass code review with or without eval), what's wrong with writing the code the way I want?
Looking at the author's received "fix", I don't understand it. I'm not a big fancy Ruby expert, but I've been through the poignant guide, I've written some medium-sized stuff with it, I've used most of the syntax constructs, and I think I get the idioms. The original makes sense; it's clear to me. We do three string format operations, and eval each one, thus defining a module each time. Great.
The "fix" confuses me: "what's Module.new (I thought you just did 'module Name; stuff; end')?", "what's define_method (it looks like def, but why doesn't it just say def)?", "what's Object.const_set, and why don't I see 'name' until then?". With some reasonable inference, these aren't tough questions, but there remains one: "what the hell is the control flow diagram for this?". There are three anonymous functions defined in here, and I have no idea when the inner ones execute, or worse, are defined or compiled. I thought I understood Ruby's control flow, and I could make a guess at this, but there's no way I'd bet money on the result.
So what if eval turns code into strings? Code _is_ strings! Do you think files are made of parse trees? eval doesn't hide information, it adds another level of abstraction (and there's an old saying about solving problems in computer science somewhere in there). Syntax highlighters, test coverage reports, static analyzers, and cyclomatic complexity calculators (really?) should all be able to handle it. Why? Because the feature is there, and it makes my life easier sometimes, and in those times, I want to use it.
So, umm, there! That's what I think about eval.
- tptacek 17y agoWho said Ruby was the "English with some bits of punctuation" language? That isn't even the idea behind a DSL.
- leif 17y agowhy did
- patatador 17y agoThat didn't prevent him from writing Camping... http://github.com/judofyr/camping/blob/fa8802511fd745dedcbeab61d809ddf15af80e43/lib/camping.rb http://github.com/judofyr/camping/blob/fa8802511fd745dedcbea...
- Porfir 17y agoActually, it's a bit of both. He sometimes writes some very "hackish" yet astute code, but his APIs are always cristal clear (and fun to use).
- jamesbritt 17y agoHe was wrong.
- raganwald 17y ago"Code is strings" in exactly the same sense that "Speech is vibration of molecules." The problem with eval-ing strings is that it doesn't scale. It's great for building three identical modules "B," "C," and "D," but the moment you want to do something interesting, it breaks down. The complexity of manipulating programs as strings grows far more rapidly than the complexity of things you want to do. For example, String#to_proc adds some syntactic sugar to Ruby like implied parameters so you can write things like: some_array.map(&'+ 1'): http://github.com/raganwald/homoiconic/blob/master/2008-11-28/you_cant_be_serious.md#readme http://github.com/raganwald/homoiconic/blob/master/2008-11-2... The implementation is hideous: http://github.com/raganwald/homoiconic/blob/master/2008-11-28/string_to_proc.rb http://github.com/raganwald/homoiconic/blob/master/2008-11-2... That's because it's trying to manipulate and eval strings that represent program syntax where it should be parsing the strings and manipulating data structures that represent program structure.
- rw 17y agoReg, what's your take on the enhanced syntax that comes with PLT Scheme macros? Do those scale? The code in that isn't just a list, it also has contextually-meaningful information. http://docs.plt-scheme.org/syntax/index.html http://docs.plt-scheme.org/syntax/index.html
- leif 17y agoI'm not saying eval does scale, I'm just saying it's not evil. Of course, if I want to actually manipulate the parse tree, I should parse the string first. But if I don't need that kind of power, there's no sense in contorting my code to fit into the awkward metaprogramming constraints of <language>.
- raganwald 17y agoI (also) never said it was evil, I said it doesn't scale. But that being said, I have seen many tools start out being used just as you say, benignly, in places where they offer convenience for simple cases. Open classes a/k/a monkey patching falls in this category for me: a tool that works well for certain straightforward cases. However, programmers seem to have a reach that exceeds their grasp of the limitations of their tools, and over time people push the tools right out of their sweet spot and into trouble. That's not the tool or technique's fault, of course. If people want to amend core classes with hundreds of kitchen-sink convenience methods or eval much more complex string manipulations... You might easily say that is the fault of the programmer for making a poor choice.