Live data from Hacker News

Rails – The Missing Parts

eng.joingrouper.com

161–170 of 173 posts

Re: Rails – The Missing Parts

#161

Earlier quoted context omitted.

Controller method that I can share? No. This method in mime-types is reported by Code Climate as a code smell. They're wrong: it's the smallest it can possibly be while still correctly performing the necessary goal; any smaller, and you have to break it into multiple smaller methods that provide no value except keeping Code Climate happy. https://github.com/halostatue/mime-types/blob/master/lib/mim... The method is ~…

> They're wrong: it's the smallest it can possibly be while still correctly performing the necessary goal; any smaller, and you have to break it into multiple smaller methods that provide no value except keeping Code Climate happy. Wrong? Smallest it can possibly be? Those are strong claims. I definitely disagree with Code Climate from time to time. But I try to keep an open mind. I've found that trying to follow dum…

Your extraction attempt actually proves my point: your code is more complex, is less readable, is demonstrably wrong, and destroys performance in at least two ways (I’d benchmark my “ugly” code against yours every time and win).

More complex and less readable: you’ve taken the comparison out of context of the class which is being used for comparison and put it in a different class and file that has to be opened for understanding a priority comparison. Worse, that separate class and file isn’t going to be reusable for anything else, because it depends heavily on the (admittedly large, but justifiably so) public interface of MIME::Type. So, readability is made worse for the sake of a dubious improvement in testability and no value in reuse.

If your editor supports code folding (it should, and you should be using it), then you don’t even have to see the implementation of `priority_compare` if you don’t need it.

Demonstrably wrong: you’re calling `#simplified_value` twice. You could make that not as ugly by caching, but that’s already known to be a waste of time because your extraction…

Destroys performance: `priority_compare` is used for sorting (as the code comment states outright). Creating a new object for each and every comparison is going to send sort performance to hell in a handbasket with rockets on it. It’s the same problem that plagues people who use decoration heavily: performance sucks and memory use gets ugly quick. The calling of `#simplified_value` twice doesn’t help here, and caching the value only makes memory use worse.

The code comment on `priority_compare` is clear: it’s a specialized implementation of `` used for sorting from MIME::Types#[]. That should immediately halt any consideration of extracting the code into an object that needs creation, and continuing on with that is a failure of good software development in favour of purity suggested by stupid rules. Even extracting it into a class method is of highly questionable value, because now you have to (as you do with your extraction) know the left and right comparison objects, rather than (safely) assuming that the undecorated version is the object itself. It’s rather the difference between operators overloading in C++ where you need to provide both left and right values vs only providing the right value because the left value is the object itself.

I considered separating the if/elsif conditions to separate methods, but you still need the if/elsif conditions, and all you’re doing is pushing code around in ways that, once again, will not be used outside of `priority_compare`.

I had considered implementing `priority_compare` at the call-site, but it’s used at two places in MIME::Types. So, the `priority_compare` is reused, but the component parts aren’t, really.

I will admit to laying a trap with `priority_compare`: I’ve worked on this code off and on for ten years. Code Climate, being a naïve program, cannot understand how the code is going to be used, but only understands how it’s defined and measures it against some fairly simplistic and stupid metrics. They can be interesting when you are first approaching a program to understand hotspots, but their value drops to zero very quickly compared to the understanding you have from working with the code regularly.

Where I think Code Climate (and similar tools; they just happen to be fairly high-profile in the Ruby community) goes wrong is that a lot of inexperienced and naïve developers tend to treat it as Truth that Must Be Followed. Many of these folks are also fans of so-called “Clean Code” techniques and otherwise lack the experience necessary to know when not to follow these sorts of rules and assume that Code Climate is good becaus it simplifies the score to a GPA/grade.

Re: Rails – The Missing Parts

#162
When reading DHH's comments it's important to remember that the domain model for Basecamp is extremely simple. It's a brilliant piece of software that's been well thought out, but the underlying domain concepts are extremely basic.

I wonder if he's ever worked with an app that has a complicated domain.

His comments taken from this perspective make a lot of sense. Rails was written for Basecamp.

For large apps with real complexity, the rails way falls short.

Re: Rails – The Missing Parts

#163
post #39

The proof is always in the pudding. While there are good and reasonable times to introduce "interactors", this particular example is poor. The tests presented are anemic, and the code is absolutely not any clearer by being extracted and wrapped. I would indeed have kept all this in the controller. The key point for an "interactor" extraction is imo when you have multiple models being created in symphony, like a Signu…

Large - yes, but with an extremely simple domain model (and better for it).

Re: Rails – The Missing Parts

#164

Earlier quoted context omitted.

You're really against Code Climate huh? Just what did it do to you to garner such hatred? I'm not personally a fan but I can see how it may help large companies in certain situations. Anyways, when I asked about a "maximum" I was not asking in absolute terms. What do you see as a reasonable max for the majority of use cases? At which point do you start feeling bad about your method?

I'm against Code Climate because it promulgates nonsensical metrics in ways that are actively harmful to good engineering. Just like Bob Martin and his concept of “clean code”. All of these things are at best sigil markers. They aren't solutions, and they can't provide any answers. I don't have a max length to a method, because I'm not a prescriptivist. What I have is a point where I stop understanding what a method…

I hope I wasn't a contributor to the 3,000+ line function you're describing.

Re: Rails – The Missing Parts

#165

Earlier quoted context omitted.

I'm against Code Climate because it promulgates nonsensical metrics in ways that are actively harmful to good engineering. Just like Bob Martin and his concept of “clean code”. All of these things are at best sigil markers. They aren't solutions, and they can't provide any answers. I don't have a max length to a method, because I'm not a prescriptivist. What I have is a point where I stop understanding what a method…

I hope I wasn't a contributor to the 3,000+ line function you're describing.

No, that's an earlier company I worked at. It existed before I got there, and I suspect it's still there now.

Re: Rails – The Missing Parts

#166

Earlier quoted context omitted.

Where did I say Rails should provide this? My point was primarily that attempting to convince DHH of your architectural choices is sisyphean and ultimately pointless since he has crafted a nice bubble for himself where he doesn't have to be exposed to architectures or complexities that he finds distasteful.

> The thing which Rails and DHH offer no guidance whatsoever is the separation of persistence from the domain model. This seems to suggest you were looking for guidance or sane defaults for this. If that's not what you intended it to mean, I'm sorry for misreading it.

Your interpretation is not what I intended but neither is it completely unfair.

I am looking for guidance (or rather good discussion and ideas) about how to address this issue for larger Rails apps, just not from Rails or DHH. I don't think it's Rails' place to do this since I don't really think a one-size-fits-all approach is right and it sort of tramples over the core philosophy of ActiveRecord which I believe is a useful default. On the other hand I don't buy into DHH's philosophy that its all astronaut architecture either.

Re: Rails – The Missing Parts

#167

Earlier quoted context omitted.

You're really against Code Climate huh? Just what did it do to you to garner such hatred? I'm not personally a fan but I can see how it may help large companies in certain situations. Anyways, when I asked about a "maximum" I was not asking in absolute terms. What do you see as a reasonable max for the majority of use cases? At which point do you start feeling bad about your method?

I'm against Code Climate because it promulgates nonsensical metrics in ways that are actively harmful to good engineering. Just like Bob Martin and his concept of “clean code”. All of these things are at best sigil markers. They aren't solutions, and they can't provide any answers. I don't have a max length to a method, because I'm not a prescriptivist. What I have is a point where I stop understanding what a method…

"had a 3,000+ line function that was nearly impossible to factor out"

Sounds like the only reason it was nearly impossible to factor out was because someone didn't stop at line 500 and say "hey this is getting out of hand".

Re: Rails – The Missing Parts

#168

Earlier quoted context omitted.

> They're wrong: it's the smallest it can possibly be while still correctly performing the necessary goal; any smaller, and you have to break it into multiple smaller methods that provide no value except keeping Code Climate happy. Wrong? Smallest it can possibly be? Those are strong claims. I definitely disagree with Code Climate from time to time. But I try to keep an open mind. I've found that trying to follow dum…

Your extraction attempt actually proves my point: your code is more complex, is less readable, is demonstrably wrong, and destroys performance in at least two ways (I’d benchmark my “ugly” code against yours every time and win). More complex and less readable: you’ve taken the comparison out of context of the class which is being used for comparison and put it in a different class and file that has to be opened for u…

Wrong: I'm sure it is. I did it without tests and didn't go through the logic carefully since that wasn't at all the point. The design was.

Performance: could be. If your context is one where performance is paramount and trumps readability/maintainability, that may certainly be easier to achieve with less factored code. I spent zero time trying to optimize the code.

I suspect this design doesn't make that as hard as you make it sound, though. My team writes code in the style of my example, and we don't have problems optimizing when it's called for. Though we avoid optimizing at the expense of readability unless we see a real problem.

I find it interesting that you think my example is clearly "more complex" and "less readable". I, of course, feel it is the other way around.

The fact that you've worked (mostly on your own, going by the contributor stats) on this library for ten years will of course mean that you know your way around it.

As a visitor to the codebase, I see big classes and big chunks of code that require me to load a lot into my head and digest it before I can make sense of it. Breaking that up a little means I can make sense of a smaller piece of more self-documenting logic, then dig down to lower abstractions as needed.

If you're saying that you find your way around your code better than my refactored code, I believe you.

If you're saying you think the refactored code would be harder to understand for the average developer, I think you're dead wrong.

Re: Rails – The Missing Parts

#169

Earlier quoted context omitted.

Fair enough—I was being a bit of an asshole. However, when you start your contribution to the thread by insinuating DHH is above reproach, I'm not filled with sympathy. Especially when his architectural hipsterism is IMHO responsible for ruining a couple microgenerations of developers who learned to code through rails. I can't be the first guy who's put his head through a wall upon hearing you say persistence is part…

To be fair, a great many of web apps can justifiably say "my domain is the data store." In fact, whenever I use BaseCamp, that's exactly what strikes me almost immediately. Stock rails tends to be a great fit in those cases; your business objects are bags of data. Of course, those projects don't happen to be all that interesting to work on technologically, but I wouldn't want to work on MS Access "apps," either.

That's incidental isomorphism between the two, and its different from your domain being your data store. You're right, there's a great many apps that can get away with it for awhile. And for those apps that fit in that mold and just kind of stall out or never grow, more power to them. Any app that continues to grow in terms of features or scale WILL break out of that mold—unless they're tethered so tightly to it that it becomes an anchor (which, let's face it, is most rails apps in the wild.)

Re: Rails – The Missing Parts

#170
post #39

The proof is always in the pudding. While there are good and reasonable times to introduce "interactors", this particular example is poor. The tests presented are anemic, and the code is absolutely not any clearer by being extracted and wrapped. I would indeed have kept all this in the controller. The key point for an "interactor" extraction is imo when you have multiple models being created in symphony, like a Signu…

How long does the Basecamp test suit (excluding any integration tests) take to run?
Post reply on HN