5 ms·
I agree with the objection mentioned in the OP's comments: eval() as described turns code into strings. As Alan Perlis said: "The string is a stark data struct
by raganwald 17y ago
I agree with the objection mentioned in the OP's comments: eval() as described turns code into strings. As Alan Perlis said:
"The string is a stark data structure and everywhere it is passed there is much duplication of process. It is a perfect vehicle for hiding information."
(You're tired of the canonical link, so here's a much more fun one: http://www.emacswiki.org/emacs/perlisisms.el http://www.emacswiki.org/emacs/perlisisms.el)
Strings hide information, and string representations of programming languages hide the most important things about programs (with the possible exception of programming languages designed to manipulate strings, like SNOBOL).
OTOH I like using ParseTree to convert Ruby programs into s-expressions and to Ruby2Ruby convert those s-expressions into strings before evaluating them. It's overkill at the moment, but somehow it seems to point towards something much, much better than strings:
%w[B C D].each do |name|
eval(
Ruby2Ruby.new.process(
s(:module,
name.to_sym,
s(:scope,
s(:defn,
:call,
s(:args),
s(:scope,
s(:block,
s(:call,
nil,
:puts,
s(:arglist, s(:str, name))
),
s(:zsuper))
)
)
)
)
)
)
end
It's ugly, but at least it tries to represent the structure of the Ruby code.
- leif 17y agoThat 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.
- eru 17y ago> (You're tired of the canonical link, so here's a much more fun one: http://www.emacswiki.org/emacs/perlisisms.el http://www.emacswiki.org/emacs/perlisisms.el) From there: "Recursion is the root of computation since it trades description for time." I don't get it. Is recursion supposed to be slow?