TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

The Grep Test

284 点作者 phleet将近 12 年前

50 条评论

VeejayRampay将近 12 年前
So basically I can&#x27;t commit anything containing the slightest form of metaprogramming? Seems a bit extreme to me. A solution is to go for the more concise and robust metaprogrammed piece of code (the example of the form with the User object is a good one) and add a comment mentioning the methods called in there.<p>The &quot;smartass&quot; way of programming is sometimes overused but it does have its benefits. When you&#x27;re metaprogramatically setting the attributes on the User, you&#x27;re also avoiding needless and error-prone repetition and making sure that this central piece of code will either crash all the time or work all the time for all attributes. This has tremendous value.<p>So while I understand the point about this article, I might want to add a pinch of salt to the dogma underlying it.
评论 #6033733 未加载
评论 #6033981 未加载
peterhunt将近 12 年前
The point here is not that metaprogramming is universally bad, it&#x27;s that it should be used as a last resort (or second-to-last resort to codegen, depending on your platform&#x2F;application) and you should feel bad when you need to use it.<p>Simply using it to save keystrokes is pretty lame since you&#x27;ll spend much more time maintaining code than typing out the original and explicitness is valuable when returning to a piece of code. Additionally, if you find yourself that you need a lot of metaprogramming for a lot of things it&#x27;s often an indication that you could just refactor your code using static idioms and be better off.<p>Not to mention that the more you use metaprogramming, the more likely it is that you or someone else will kill some runtime optimizations of the JIT.<p>IMO, syntax matters way less than people tend to think it does, and the additional implementation complexity and astonishment cute syntax introduces tends to make the trade-off not worth it.
评论 #6033999 未加载
评论 #6036346 未加载
评论 #6034458 未加载
评论 #6034324 未加载
danso将近 12 年前
&gt; <i>I’m sure by this point, a few of you have thought “Hey, but Rails fails the Grep Test!”. This is absolutely true, most notable due to the dynamic find_by_</i> finders, and the dynamic <i>_path URL path generators.</i><p>OK, sure, but after you&#x27;ve grokked the first &quot;find_by&quot; usecase...do you really need documentation for all the other kinds of &quot;find_by&quot;&#x27;s that you&#x27;ll use?<p>In any case, I&#x27;d agree that meta-programming is too often abused, but the proposed grep test is far too strict. And, inability to create complete documentation for every single kind of method token is not really the main reason to avoid meta-programming...I&#x27;d say performance and the propensity for abuse are better motives.<p>This pull request re: removing most of Rails&#x27; dynamic finders in 4.x covers the topic nicely:<p><a href="https://github.com/rails/rails/pull/5639" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;rails&#x2F;rails&#x2F;pull&#x2F;5639</a>
评论 #6033674 未加载
pjungwir将近 12 年前
Yes, grepping for a function and not finding it anywhere in the codebase is very annoying. I&#x27;ve had to maintain this sort of thing before. It&#x27;s like in bash saying `${FOO_$BAR}` (if such a thing is possible). It gives me shudders.<p>I also agree that Rails gets a pass. It&#x27;s a little different when you have a stable (well, sort of :-) API with dozens of books and thousands of blog posts. It was annoying to learn what was going on at first, but that knowledge is more long-lasting so worth a bit more pain.
评论 #6033609 未加载
评论 #6036262 未加载
stiff将近 12 年前
The examples shown in the post aren&#x27;t wrong because they fail the grep test, they are wrong because they A) capture an uninteresting abstraction that is not likely to see much usage as the program gets more complex, B) mix up domain code with tooling code that if at all gets developed should end up being part of a framework, plugin, base class etc.<p>The general underlying problem is that a lot of people stick with those &quot;principles&quot; (which are rules of thumb, often weak ones at that) they have read somewhere without developing a real understanding of software design. Slogans like DRY or SRP seem to blind people to often simple forseeable consequences of their design decisions.<p>Software design boils down roughly to two abilities: one is imagining a great many ways of structuring a program, the other is the understanding of practical consequences of a given program structure. So a good software designer must ask him- or herself: why code repetition is a bad thing? And the answer is that there is absolutely _nothing_ wrong. What is wrong is that a logically or structurally common aspect of the problem didn&#x27;t receive the recognition in the form of an abstraction (a method, class, variable, interface ...). Then you waste time by not being able to reuse this abstraction, when something about this common aspect changes you are forced to go through fifty places and modify the code, but the worst thing is that there is a limit of the amount of details a programmer can keep in his or her head, and the less you are able to structure your program the more restrictive will be limit of the problem complexity you will be able to tackle. That&#x27;s the reason software design is at all important.<p>There are cases however when there is no real logical common denominator to two pieces of code and they are similar practically by accident. It is just as wrong to abstract an accidental similarity as it is not abstract an existing one; soon the requirements change and the abstraction will have to be abandoned, code copied and developed in divergent ways.<p>Finally, people start attempting metaprogramming way before they had learnt enough about structuring programs using basic means, like breaking things down into classes and methods appropriately, data-driving your programs etc. Yes, this is actually a skill, and unless you rewrite some of your own programs 5-10 times and compare their structure you won&#x27;t learn it. I also recommend reading some classical books: SICP, Refactoring, Refactoring To Patterns, Effective Java, Programming Pearls.<p>And the ultimate lessons come from maintaining your own code for a few years.
评论 #6035838 未加载
评论 #6034840 未加载
评论 #6035502 未加载
shurcooL将近 12 年前
No, this is wrong, wrong, wrong.<p>Ok, it&#x27;s actually right under one false assumption: that we are limited to using our existing text-based tools like text editors, grep and so on. As long as we use these existing tools, this advice is quite valid.<p>However, we are absolutely not limited to existing tools, we can and should make new ones that augment how we work and allow us to reach more dryness without compromises. You could have tools that let you work with ASTs, that expand code on the fly, show you higher level information, let you debug and step through sections of code effortlessly.<p>In the end, dryness is good, because it means you have less repetitive work to do when things change (and software is all about changing, unless you don&#x27;t want to make progress). So it&#x27;s very well worth investing into being able to achieve dryness more naturally without the downsides.<p>To quote Bret Victor, stop &quot;blindly manipulating symbols.&quot; (You don&#x27;t have to do do so overnight, just as long as it&#x27;s a goal you work on achieving as time goes on.)
评论 #6034117 未加载
评论 #6034083 未加载
评论 #6036841 未加载
评论 #6035277 未加载
forrestthewoods将近 12 年前
Yes yes yes. It&#x27;s important to have code standards that enable code to be easy to understand easy to navigate.<p>I work in C++ all day and loathe when functions are fully implemented in the class declaration. Keeping them seperate with full ClassName::FunctionName(...) scoping makes finding functions exceedingly simple and friendly. Keep implementations separate means the full class declaration is easy to read, parse, and understand. I don&#x27;t want to scroll through hundreds of lines of code just to see what functions are available.
评论 #6033973 未加载
评论 #6035859 未加载
pnathan将近 12 年前
Sorry, don&#x27;t buy it.<p>A published &amp; concise interface wins over an undocumented redundant interface. Explicit-only just takes you down the path towards Java and COBOL.
评论 #6033598 未加载
评论 #6036516 未加载
评论 #6034203 未加载
评论 #6033456 未加载
评论 #6033721 未加载
calinet6将近 12 年前
Ehhhhhhhh not really. If you&#x27;re using metaprogramming or abstract programming of any kind, it&#x27;s <i>usually</i> for a good reason, and DRY in itself is worth simply not being able to find every single reference to your metaprogrammed item in your codebase.<p>It&#x27;s an artefact of the design. You simply need to know how the abstraction is done, and then you look for invocations of that abstract more general form. It&#x27;s not that difficult, and if it&#x27;s being done, it is almost without exception a better way to do the thing.<p>If metaprogramming is not a better way to do the thing being done, and adds confusion and decreases reusability, then you shouldn&#x27;t do it, but that&#x27;s a tautology and doesn&#x27;t mean we have to be able to grep for everything we ever write.
评论 #6033814 未加载
dfan将近 12 年前
This is the second time this week I&#x27;ve seen &quot;counterexample&quot; used to mean &quot;something that is bad because it breaks the rule, thus showing why the rule is good&quot; rather than &quot;something that invalidates the rule, thus showing that the rule is bad&quot;. Is this a real trend in usage or have I just been unlucky recently?
评论 #6034647 未加载
Periodic将近 12 年前
One thing that can often help with this is to have a good REPL. With it you can dive into and explore the code as it is at runtime. For example, a common way that I figured out Rails was to open the console and use obj.methods to see what methods are available.<p>Other languages in which I&#x27;ve enjoyed REPLs include Python, JavaScript and Haskell. Two languages I have not found a good REPL for are Java and C++. Is anything of this sort available there?
评论 #6033708 未加载
评论 #6033651 未加载
评论 #6034358 未加载
recursive将近 12 年前
If you think this is good, wait until you find out about statically typed languages and IDEs with code navigation features.
评论 #6033800 未加载
评论 #6033816 未加载
评论 #6037790 未加载
klochner将近 12 年前
An important distinction is between mature (or matur-ish) library code and your consuming code base:<p><pre><code> - library code publishes an interface and can do what it wants - your client&#x2F;application code should be greppable </code></pre> There isn&#x27;t a sharp distinction between the two, but it&#x27;s a pretty big headache if developers are using heavy metaprogramming everywhere in your project.
评论 #6033824 未加载
agentultra将近 12 年前
I must be pedantic and separate the definition of &quot;metaprogramming,&quot; and &quot;dynamic programming;&quot; of which this is the latter.<p>The reason this difference is important is that <i>metaprogramming</i> is structured and explicitly defines the change in the program&#x27;s semantics.<p>Thankfully I have never seen code like what was posted in my experience with Python so far. <i>Explicit is better than implicit</i> which the code example in this post would fail to pass IMO. Dynamically dispatching to names that don&#x27;t exist in a class&#x27; published interface at call-time is a big no-no in my book.<p><i>Although practicality beats purity.</i><p>I haven&#x27;t seen it yet but that doesn&#x27;t mean there is a practical reason to use this method of dynamic dispatch. If there were one and it gets a problem solved NOW rather than waiting to find a better solution -- it might be worthwhile.<p>However it&#x27;s a price you have to pay.<p>I think the grep-test is at least a good way to test the waters with a bit of code. I don&#x27;t think it&#x27;s a universal end-all-discussions rule.
评论 #6038046 未加载
评论 #6033943 未加载
rralian将近 12 年前
I totally agree with this. It&#x27;s one of my pet peeves... dynamically generating method names so you can&#x27;t actually search for them. Personally, I think code readability is one of the greatest goods in programming, and in general I would tend to place it above DRY as a priority (within reason)... particularly for mature, large, complex projects that require large teams (meaning lots of new people). And for the most part that&#x27;s what I&#x27;m always hoping I&#x27;m building.
willurd将近 12 年前
I don&#x27;t necessarily disagree with the article, but maybe the solution is a new kind of search. One which understands languages, statically analyzes a source tree, and searches the ASTs for the tokens you&#x27;re interested in.<p>This would also have the side benefit of being able to produce better designed search results.<p>EDIT: I suppose searching the AST wouldn&#x27;t be enough, you would have to evaluate the code to some extent to be able to search these properties.
评论 #6034187 未加载
zackbrown将近 12 年前
<i>When working with dynamic code, it’s an incredible boon to productivity to be able to quickly locate the definition of functions so you can build a complete mental context about what’s going on.</i><p>Imagine the &#x27;incredible boon to productivity&#x27; you could get from tools (text editors, IDEs) that can deterministically show you all references or definitions of any method, variable, or class throughout your codebase whenever you want. (Hint: this isn&#x27;t a dream--this is a huge plus of working with statically typed languages.)<p>For all of the pop-trendy love that dynamic languages seem to get for &#x27;being fast for development,&#x27; (read: hacking) it&#x27;s tragic how much they slow you down when you need to start hunting down where the hell something was magically (or meta-) declared or changed, especially when you&#x27;re working with someone else&#x27;s code (read: real life.)<p>The grep test seems like a great approach if you&#x27;re stuck with a dynamic language. Of course, we don&#x27;t always have the luxury to choose the technologies or platforms that we work with, but you&#x27;ve got the choice, a statically typed language solves this problem out of the box.
评论 #6035058 未加载
mnarayan01将近 12 年前
I think this is a legitimate issue, though I&#x27;m not sure I really agree...there just seem to be too many places where it provides too much utility. That said, I tend to change my opinion on the topic fairly frequently, based upon whether I was last writing something where dynamic function declaration was convenient or last looking for where a function was declared.<p>One thing I think the post might emphasize more thoroughly is that dynamic function invocation (at least when the function is defined in the project scope), is probably <i>far</i> more problematic than dynamic function declaration, particularly if sometimes the function is explicitly invoked, and sometimes dynamically. In this situation, I&#x27;ll generally try to document that the function is dynamically invoked with the function declaration, but I&#x27;m always unsure what exact information I should put there. Simply saying something like &quot;Dynamically invoked -- grep will not find all usages&quot; is a minimum, but I often want to add more than just that.
评论 #6033749 未加载
smrtinsert将近 12 年前
Another one of those things you never have to worry about if you use a statically typed language.
评论 #6033473 未加载
评论 #6033532 未加载
评论 #6036146 未加载
评论 #6033610 未加载
评论 #6033670 未加载
评论 #6033476 未加载
toddkaufmann将近 12 年前
My first impulse is this is stupid. It means your tools aren&#x27;t smart enough. Use an IDE, use aigrep, some tool that knows what to look for.<p>A better title would be &quot;Don&#x27;t use a fastening device if it fails the hammer test.&quot;<p>Are you don&#x27;t use a tool that generates SetFunkyColumnName from funky_column_name data spec ? Or &quot;I can&#x27;t find the click handler in the .html, quit using jQuery&quot; ?<p>I have been at the bottom of steep learning curves multiple times where I couldn&#x27;t figure out where stuff was coming from. In most cases I got over it<p>Use the appropriate tools that get the job done and make you and your team productive. Tools and ideas evolve at different rates. Not all tools or ideas are implemented properly the first time, and not all tools or ideas are necessarily good&#x2F;useful. But we&#x27;ll never get any further if we don&#x27;t try...
dbloom将近 12 年前
The &quot;grep test&quot; doesn&#x27;t just help humans and IDE&#x27;s. Closure Compiler&#x27;s ADVANCED_OPTIMIZATIONS mode (<a href="https://developers.google.com/closure/compiler/docs/api-tutorial3" rel="nofollow">https:&#x2F;&#x2F;developers.google.com&#x2F;closure&#x2F;compiler&#x2F;docs&#x2F;api-tuto...</a> ) only works with JS code that can pass the &quot;grep test&quot;. Setting or getting properties using dynamically generated property names won&#x27;t work (even if Closure Compiler could understand your intent, it would have to know at runtime which minified name the concatenated parts should result in).<p>So in this case, writing longer, &quot;grep-friendly&quot; JS code can actually reduce the size of the JS payload you serve to your users.
wizzard将近 12 年前
There is always going to be code that takes more than grep and a glance to understand. Sometimes you won&#x27;t fully grok it until you&#x27;ve stepped through it line by line, even without &quot;tricks&quot; like metaprogramming. And more often than not the &quot;tricks&quot; make it more concise, less prone to bugs, and easier to understand.<p>It&#x27;s madness to classify all use of metaprogramming as abuse. Perhaps you need to pour a glass of wine and learn to savor the source code, and to appreciate the power of modern programming languages.
swah将近 12 年前
Or... we improve the tools, instead of limiting the expressiveness of languages we use just to make grep happy.<p>(See Yegge&#x27;s grok project, unfortunately he doesn&#x27;t blog anymore)
TylerE将近 12 年前
Can&#x27;t say I agree with this. A decent IDE has no problem tracing usage of dynamically generated methods etc. I know the JetBrains stuff can for Python and Ruby.
评论 #6033428 未加载
评论 #6033397 未加载
评论 #6033515 未加载
gwu78将近 12 年前
Why not use a system of (unified) comments interspersed in the code to demarcate various elements? A sort of index.<p>The idea is that programming languages allow too much flexibility in form and syntax for any indexing system to accomodate the full range of possibilities. And &quot;coding style&quot; rules are apparently too restrictive on creativity: they are too difficult to enforce. And hence a solution would be better to focus not on the code, but on the comments. Force programmers to adhere to a uniform commenting system.<p>The OP mentions ctags. It&#x27;s not a perfect system, but it&#x27;s still in the BSD base systems so everyone who has BSD has a copy of the needed programs. That&#x27;s a start.<p>What about cxref? Another old system that&#x27;s probably not perfect, but seems like it was aiming in the right direction.<p>I&#x27;ve never understood why programmers obsess about things like verbose function names (that make lines go way over 80 chars and bend across the page... with identation it becomes almost unreadable to my eyes) instead of just providing an index of all functions and including the verbose information in the index, not the code. vi (and no doubt emacs too) allows you to jump around easily so you could look things up in an index quite quickly.<p>Why do Wikipedia pages have an index of footnotes and references at the bottom? Why not stuff all this information into the words in the body of the article? Why do books have indexes? Why do academic papers use footnotes? I don&#x27;t know. But I&#x27;m accustomed to these conventions.<p>I also don&#x27;t know why code uses verbose function names and generally lacks an index or footnotes. But I guess programmers have just become accustomed to these conventions.
ascotan将近 12 年前
&quot;As a broad generalization, I would say dynamic declaration is occasionally worth the tradeoff, but dynamic invocation is almost never worthwhile.&quot; &lt;-- huh? What does this even mean?<p>This entire post is silly.<p>1. Not being able to grep for code has nothing to do with being DRY.<p>2. Being able to grep for something doesn&#x27;t make it correct. Nor does it make it less maintainable if you don&#x27;t used named functions.<p>Moving on...
jimmaswell将近 12 年前
This is a little silly. My game engine dynamically invokes lambdas, and script files dynamically added to Actors at runtime with reflection, and such all the time, and it&#x27;s well-documented and maintainable. I can&#x27;t think of a reasonable way to implement this stuff that passes this grep test. Unity development fails it too I guess?
michaelfeathers将近 12 年前
<i>The Grep Test</i> is interesting, but it is too extreme for me. I have this thing I call the &#x27;No Lie Principle.&#x27;<p>The idea is that when you look at code, the computations you see are the ones actually executed. Meta-programming may be used but only to add behavior to existing code, not to nullify it.<p>A good example is an &#x27;execute around&#x27; method. The method you see in the code <i>is</i> executed, but some things may happen before it and some things may happen after it. What you can&#x27;t do is replace the body with something else.<p>An interesting thing about the &#x27;No Lie Principle&#x27; is that aligns with good practice around inheritance also. It&#x27;s better to override abstract methods than it is to override concrete ones for a number of reasons.
Arnor将近 12 年前
Things are even worse in the PHP world than the languages described in the article. You get variable variables and you can use variable as the function&#x2F;class names so this is totally valid:<p><pre><code> function do($class, $action, $param, $value) { $method = $action.$param $obj = new $class(); $obj-&gt;$method($value); return $obj } $my_name = &#x27;Arnor&#x27;; $$my_name = do(&#x27;Entity&#x27;, &#x27;set&#x27;, &#x27;Name&#x27;, $my_name); &#x2F;&#x2F; The entity is now stored in the variable $Arnor </code></pre> Thanks PHP... Don&#x27;t even get me started on __call.<p>It&#x27;s fun to come up with clever solutions and puzzles, but it harms your code base. If you&#x27;re proud of how new and clever your last 10 lines were, you <i>probably</i> need to refactor it.
themstheones将近 12 年前
This is dumb. Most languages support some way of autoloading classes. If you don&#x27;t understand that then you won&#x27;t be grepping the right file. As such this is not a valid test for readability because understanding how classes is loaded is assumed.
评论 #6033583 未加载
gohrt将近 12 年前
It&#x27;s a noble concept, but a bit weak. Really what you want is a static analysis tool that an keep up with your programmers.<p>For example, Guice fails the Grep Test hard, but it incredibly helpful.<p>All data-driven fail the Grep test. Your browser fails the Grep test (you can&#x27;t grep for javascript content)<p>You just need to replace Grep with an xref tool that <i>understands your programming language</i>, including your metaprogramming. This may require you to commit your configuration files and standard data objects into your source control, or build an indexer that can read your CMS as well as your code.
ilcavero将近 12 年前
what about functions passed as arguments? quite a basic technique and I don&#x27;t think it passes this test.
评论 #6033463 未加载
评论 #6033470 未加载
flashmob将近 12 年前
One should not get too dependent on just one tool as Grep, sacrificing some useful features of dynamic languages... In the Javascript example, (and possibly others), it is still possible to easily find where the method was defined - open a debugger, add a break point on console.log(ray.getPosition()); and step in to it. there are many other tools to help you, for example, many modern IDEs have powerful inspection features these days.
jol将近 12 年前
now I have a test for the &quot;too abstract&quot; problem. Also - bonus points to the author for pointing out at the end that general practice != abolute truth
rocky1138将近 12 年前
This seems like a great case for solid comments in the code, as long as they&#x27;re up-to-date and you don&#x27;t have a huge number of permutations. I know we all like to crap on code comments here, but if you had say 5 possible permutations that this code supported, a programmer could easily throw a comment above it with each of the supported functions, comma-separated. Then grepping would indeed find them.
ColinWright将近 12 年前
So, basically, everyone who is capable of producing excellent code is bared from using a powerful technique, largely because some people can&#x27;t understand the code they produce.<p>It&#x27;s a difficult trade-off, one one I&#x27;ve had to make calls on several times. Do you use the full capabilities of incredibly gifted and talented programmers, and then allow code into your codebase that maintenance programmers can&#x27;t understand?<p>Tricky.
评论 #6034305 未加载
dllthomas将近 12 年前
I think the grep test is inappropriate as a blind requirement for commit acceptance, but I do think it gets at an interesting issue. If your code fails the grep test, <i>pay attention</i>, make sure what you&#x27;re doing makes sense, and make sure it&#x27;s documented somewhere that&#x27;s accessible to those new to the code base (in terms of work flow as well as technical access).
wpeterson将近 12 年前
This assumes you don&#x27;t write any tests. In that case your system has more problems than the scope of this article.<p>There&#x27;s nothing wrong with using metaprogramming to generate methods, as long as you are writing tests for those methods.<p>Grepping the application code is usually much less useful than grepping the tests to see how the system is intended to behave.
softbuilder将近 12 年前
I wrote a utility ages ago to find orphaned Ruby methods. It greps (actually, acks) for method names. Naturally this only goes so far with a non-trivial Ruby codebase, which limited its usefulness. <a href="https://github.com/built/funk" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;built&#x2F;funk</a>
aaronblohowiak将近 12 年前
I wrote about this a while ago: <a href="http://aaronblohowiak.com/blog_posts/rails-maintainability-metric" rel="nofollow">http:&#x2F;&#x2F;aaronblohowiak.com&#x2F;blog_posts&#x2F;rails-maintainability-m...</a>
chameco将近 12 年前
Erm, what about first-class functions in general? This doesn&#x27;t just make metaprogramming harder, it also stops you from saving functions in lists or hash tables and any sort of higher-order programming.
serichsen将近 12 年前
This obviously only applies when grep is all you have to find-who-calls and find-definition.
halayli将近 12 年前
C macros can cause the same issue when used to concat function names using ##.
jamii将近 12 年前
In a sane language you could just ask the function where it is defined.<p><pre><code> user=&gt; (meta #&#x27;leiningen.gnome&#x2F;uuid) {:arglists ([project]), :ns #&lt;Namespace leiningen.gnome&gt;, :name uuid, :column 1, :line 10, :file &quot;leiningen&#x2F;gnome.clj&quot;}</code></pre>
penguindev将近 12 年前
choosing module and function names is an acquired art in python. I usually grep my entire code base (and ensure nothing matches) before I add a new public name.
jfarmer将近 12 年前
I like the idea of the Grep Test, but this is not a great illustration of it. These refactorings are bad not because they hide names from the developer but because they use the wrong abstractions.<p>The point of DRY isn&#x27;t to mindlessly remove code duplication. It&#x27;s to remind us to look for code duplication and keep us mindful of coupling between the various parts of our code.<p>Where two identical chunks of code that represent the same kind of work are used in multiple places we introduce &quot;algorithmic coupling.&quot; That is, whenever the work being done in one location changes, we have to make sure to change the work being done in the other location. Anyone reading this code -- whether the author, the author&#x27;s future self, or teammates -- has to remember this extra fact, increasing the surface area for bugs.<p>There&#x27;s also &quot;name coupling,&quot; viz., for every vector _foo_ associated with the Ray we want methods like foo_is_zero?, negative_foo, etc. Here it&#x27;s important that the naming convention be consistent, so there&#x27;s coupling there, too. If the names aren&#x27;t consistent anyone else reading the code would then have to remember <i>that</i> fact, and anyone changing the names would have to remember to update all the other names, too.<p>The irony of his example is that style of metaprogramming is a great way to get rid of name coupling, but he did nothing to get rid of the much worse algorithmic coupling. Indeed, algorithmic coupling screams for DRY whereas name coupling requires it on a more case-by-case basis.<p>That is, when all the names are highly localized, e.g., three short methods that share some naming pattern are all defined in succession, it&#x27;s much less important to remove the duplication. Anyone reading or editing that code will quickly see what the pattern is and why it exists.<p>Here&#x27;s a comment I left on the blog:<p>Hmm. I don&#x27;t think the lesson here is about to-DRY-or-not-to-DRY your code. Instead, it&#x27;s about using the appropriate abstractions.<p>Using the Ray example, both position and direction are vectors, not points. Make them vectors! Then you&#x27;d be able to say things like<p><pre><code> ray.position.zero? # We&#x27;d usually say &quot;the inverse of&quot; not &quot;the negative of&quot; ray.position.inverse </code></pre> Furthermore, if you wanted to define the same methods, well...<p><pre><code> class Ray def position_is_zero? position.zero? end def direction_is_zero? direction.zero? end end </code></pre> There&#x27;s less repetition, now, because you&#x27;re only repeating names, not logic. This means the code will only break when the names change, i.e., zero? becomes is_zero? or something.<p>In a world where all of your logic is also duplicated in the Ray class, the code would break when either the names or the logic changed.
fleitz将近 12 年前
This is a standard case of what I like to call a tradeoff.<p>Making code that passes the grep test allows many more programmers who are vaguely familiar with the codebase to make changes.<p>Making code that fails the grep test allows a team of a few highly skilled developers who know the codebase inside and out to do the work of hundreds.<p>It&#x27;s like mathematical notation, you generally need experience in that sub-branch of mathematics to understand the notation.
评论 #6033947 未加载
评论 #6034039 未加载
leifaffles将近 12 年前
The big elephant in the room is that this isn&#x27;t really about metaprogramming. It&#x27;s about the failure of the text as a means for manipulating of computer programs (e.g. eval on strings, reflection, method_missing, _getattr_, etc). It would be as if we represented and manipulated numbers as text strings.<p>Much like languages have more successful ways of representing numbers, some languages are more successful at metaprogramming. In particular, Lisp takes the view that the act of metaprogramming is really the act of writing application-specific compiler extensions. The default behavior simply doesn&#x27;t involve ripping apart strings and concating them back together.
dschiptsov将近 12 年前
Come on.. Anonymous functions (lambdas) have the simple rule - use them when you need a function as an argument to a high-order function (such as filter or map) right here, in this call, because giving it a name and, especially place where you can&#x27;t see its code, is less concise. If a function, it turns out, should be called more than once, it deserves a name.<p>The practice of placing any general functionality in lambdas or blocks will make thing more messy.
AsymetricCom将近 12 年前
More ways in which code is being made &quot;approachable&quot; to those who have no business reading code can pretend they have valuable input managing developers.