Settings

Theme

Steve Klabnik's response to critiques of his Ruby OOP post

blog.steveklabnik.com

34 points by tannerburson 15 years ago · 33 comments

Reader

jarrett 15 years ago

Some problems are better expressed in paradigms other than OOP. One of the beautiful things about Ruby is that you can use OOP or other paradigms on a case-by-case basis in accordance with what's best for the problem at hand. This article seems to miss the elegance of that.

Design patterns and OOP have their place, but this article adheres to them too dogmatically for my taste. It reminds me a little of this:

http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom...

When I first started programming, I wanted a set of rules which, if followed strictly, would always guide me towards the perfect architecture. I've since learned that such a set of rules doesn't exist. Instead, we have to rely on our experience and insight to tell us which architecture will solve a given problem elegantly, and which will shoot us in the foot.

The OOP absolutists seem to be looking for that same El Dorado I once wanted. Ostensibly, design patterns promise us programming bliss through tried-and-true, universally applicable architectures. But they don't. Oftentimes, they just give you more lines of code than you really need.

It sounds like I'm dumping on OOP and design patterns, but I'm not. Like I said, there are plenty of perfectly good applications for them. My point is that it takes a bit of that aforementioned experience and insight to recognize those instances when they're appropriate. Otherwise you're just painting by numbers.

  • bphogan 15 years ago

    This is absolutely my thought, but I was not able to express it as well. :)

tptacek 15 years ago

I stopped taking this post seriously when I got to "objects > functions" (at least in Ruby). I think it may be an elaborate gag.

All I can say is, if I worked in a Rails shop and checked some code in that used a helper to generate the A-Z index of a collection of models, and my boss told me, "no, you need to move that code to app/presenters/as_dictionary.rb, because that's where I've been putting my code that presents our data as_numbered_lists and as_abbreviated_snippets and as_random_selectons; it's called the Presenter pattern and we use it", I'd look for new projects.

Also, "structured programming" isn't "Programming 1.0" to "object oriented programming"'s "Programming 2.0". That is not how it works, Steve.

  • exogen 15 years ago

    And if you'd rather cowboy up some code than stick with the abstractions your team is already using, I'd be glad you left the project.

    I'm not defending these exact examples or anything, but come on. Any kid out of school can toss some code into a project that just works. It takes some discipline to write reusable code that people know where to look for later.

    • bphogan 15 years ago

      It takes more discipline to decide not to do something.

      In the case of Rails, it's a framework and the patterns of that framework are established. I know to look for models in the models directory, controllers in the controllers directory, and helpers in the helpers directory. When I come into someone else's project, it's nice to know where things are. I've inherited lots of code from consultants who know "best practices" and move from one project to the next. Some of these projects barely resemble Rails anymore.

      It's led me to ask the question "If Rails isn't good enough, then why are you using it?"

      • urbanautomaton 15 years ago

        You should try to avoid subverting a framework's conventions if you're going to use it, sure, but Rails' helpers seem more like an absence of convention. They're a dumping ground for methods that are crying out to be properly structured. Surely not even the most fervent Rails advocate would claim that it is complete and unimprovable.

        Every single helper module is mixed in to every single view instance, no matter how irrelevant it may be. There's therefore no reason to carefully choose where to put your helper functions, because they're all available, all the time. This means that a new coder coming along has no idea where to look for helper functions that might be relevant to a particular view he's creating - they could be in literally any helper, or even be helper-ified controller methods. This in turn means you end up with duplicated functionality, orphaned functions, and obsolete cruft stinking up the joint.

        As a result, any even slightly professional team must develop their own conventions regarding the placement of helper functions. These conventions need to be communicated somehow, and how better to do that than through the code itself? Once you've got a pile of helper functions that are bound by a common cause, why not give that cause a name?

      • jasonlotito 15 years ago

        > It's led me to ask the question "If Rails isn't good enough, then why are you using it?"

        That's a pretty poor question. Rails is a framework, and for the most part it works. However, that doesn't mean it's the one and true way of doing things.

        Granted, I generally agree with the article. Helpers are a step backwards.

        • tptacek 15 years ago

          Why?

          The sole purpose of a helper is to keep code out of templates and presentation out of controllers.

          How could they do a better job of that than they do now?

          Remember, the article you're agreeing with says that helpers are bad because they are "just functions". This is, in a word, crazy. It's one thing to design with objects; it's another thing to turn all your functions into classes so you can pretend you're OO.

          • fjfish 15 years ago

            So put the code in the model, where it belongs ... I rarely use helpers for anything but formatting-fu - everything else is in the model. I rarely use helpers, period.

bphogan 15 years ago

It's nice that Steve and others want to make Ruby on Rails applications better and faster.

But this post should have been the original blog post. You can't get frustrated by your audience "not getting it" if you use terrible examples or if you're lying to simplify.

This was a good explanation on the way to use presenters. The original one was not. I still don't plan to run out and use presenters everywhere because the payoff simply isn't there for most of the apps I write.

My bigger concern is that, like with most things in Ruby, a certain percentage of folks are going to just run wild with an idea, and even the simplest application is going to have a bunch of presenters in it just because someone said it was "the right way".

It's good to explain the real "why" with these concepts. What are the benefits, the drawbacks, and what will I be able to do that I couldn't do before? So I think this followup does a great job of that.

  • raganwald 15 years ago

    Your points are cogent, however blogs are more like conversations than books. With a book, you iterate a few times with your editor(s), you pass drafts around, and hopefully discover which examples aren’t clear before you publish. Everything else must wait for the second edition.

    With a blog post, you can revise the original based on feedback, but the odds are that none of the people who read it the first time will see the revision. A follow-up post is the best way to expand/expound/correct yourself.

    I agree that the first post could have been even better, but given the first post being what it was, putting out a second post seems like the right thing to do.

  • tannerbursonOP 15 years ago

    I agree, the original piece was a decent explanation of how to refactor some helper type code into a more Presenter like model. But he completely skipped out on the question of why it's a useful thing, and when it's a good fit. If that post had been by DHH or another Rails core member, we'd see it instantly picked up into the current cargo-cult trend of the month.

    That said, I do appreciate Steve's work on finding ways outside of "the one true path" to simplify Ruby code, and hope he'll continue writing these sorts of things going forward. If nothing else, the discussion surrounding the technique and it's alternatives is extremely worthwhile.

rlander 15 years ago

" Why is it in Ruby that everything is an object, even integers, yet as soon as we need to format a date, we all turn into Dijkstra and bust out structured programming?"

" ... functions don’t provide a sufficient amount of power to tackle hard problems."

" objects > functions"

Why start an otherwise well written post with such trollish statements?

There's a lot more substance in the following paragraphs but instead everyone is focusing on those.

jerf 15 years ago

One of the things that has kept me away from the Ruby community is the way it simply takes as an axiom that OO === good; if it is OO it is good, if it is not OO it is bad. Re-read that and look at how many of his arguments are "X is not an object", with little further discussion of how that actually hurts you, just, "It's not OO" so apparently that concludes the argument that it is bad. (The class method comment links off to someone else who still comes down to a great degree to it not being "objects" properly. Yes, they may be overused, but pray tell what instance information the "sine" function takes? Oh, sorry, sine object.)

Your homework is to spend three months with Haskell learning idiomatic Haskell. Yes, it's not OO. Suck it up. You won't truly understand OO until you also understand not-OO.

  • shepmaster 15 years ago

    Steve states: "objects > functions. At least in the context of getting stuff done in Ruby".

    I completely agree that one should write idiomatic code. When you write Haskell, you write idiomatic Haskell. When you write Ruby, you should write idiomatic Ruby. Objects are idiomatic Ruby.

    • chc 15 years ago

      Objects are not idiomatic in this particular case in Ruby. That's why we haven't been doing things this way for the past several years. Ruby's pseudo-functions (actually private methods on Object) and class/module functions are idiomatic. They are part of the Ruby language, and people use them all the time. Not only is this not the idiom in Rails, even vanilla Ruby projects avoid this, despite the lack of a framework pushing them in that direction. Ruby is very strongly OO, but idiomatic Ruby doesn't go out of its way to call attention to this fact. We don't fastidiously box every block just to make sure everything goes through an object interface, nor do we write 1.+(2) just to make it really clear to everyone that 1 is an object and + is a method. To create accessors, we just call attr_accessor — we don't do AttrAccessor.new(self).

      The code Steve suggests here would be more idiomatic in Java than in Ruby. That's what this reminds me of — Java's endless array of classes-that-want-to-be-functions. Next somebody's going to realize that you might want to present dictionaries in different ways, so obviously you're going to want a DictionaryPresenterFactory to create a DictionaryPresenter to your specifications (because just having a method with that functionality would not be sufficiently OO, obviously).

ww520 15 years ago

Can someone explain why "Design patterns don’t suck, Design patterns in Java suck"?

  • tptacek 15 years ago

    That statement is almost the opposite of true. The GoF patterns were invented to paper over the inadequacies of Java and C++ and make them behave more like languages like Ruby and Python.

    I think Norvig's presentation should be required reading in order to obtain your Ruby or Python programming license:

    http://norvig.com/design-patterns/

    Think of all the countless lives that could be saved.

    • DanielRibeiro 15 years ago

      That is not entirely true. GoF patterns have tons of examples in Smalltalk, which is as dynamic as Ruby/Python.

      But they are more verbose and awkward to use in statically type languages, languages without first class functions (unlike Smalltalk, Ruby and Python), and methods like doesNotUnderstand, method_missing or __getattr__.

      And languages with mixins/metaprogramming support can do pretty much all patterns in a much better way (this is easy to see on the paper[1] where Gregor Kiczales implements the patterns in AspectJ and see how much simpler they become when you have mixins).

      The biggest problem with patterns is that people start with them, instead of refactoring to them when needed [2], which leads to a lot of over engineering (which is a form of premature optimization, and we all know what Knuth said about that).

      Uncle Bob (creator of Selenium, author of Clean Code) talked about it recently: http://cleancoder.posterous.com/patterns-of-reality

      [1] http://dl.acm.org/citation.cfm?id=582436

      [2] http://www.industriallogic.com/xp/refactoring/

      • wglb 15 years ago

        I remember how we all waited with bated breath for Design Patterns to come out. It was a bit of a disappointment, I recall. Seemed kind of complicated. So now for some of our patterns we need four C++ files per object? Heck with that.

        I would disagree that there are tons of Smalltalk examples there. There are in fact a few examples, and they actually don't weigh very much, because they are pretty small, and you don't really need the whole Design Patterns concept if you are a Smalltalk dude. I have a friend who first picked up the book after programming for 17 years in Smalltalk. He put it down after scanning through the first few chapters because it was very self-evident to him.

        For young up-and-coming programmers, I recommend setting aside Design Patterns and reading everything you can find written by Peter Norvig. Start with his design patterns essay. The short version of which is that if you need design patterns, (in the sense of the book) then there is something lacking in your language. They are an unnecessarily.

        I would never recommend Uncle Bob to anyone looking to improve programmming chops. Read Norvig instead. Uncle Bob came down on the wrong side of TDD and the fellow who failed to TDD his way into a sudoko solution. Peter Norvig comes up with a different notation, not a methodology, not a design pattern, and produced a very elegant solution.

        So to improve your programming skills, avoid Uncle Bob, read Norvig, go easy on the methodology.

      • adgar 15 years ago

        > dynamic dispatch (thin of doesNotUnderstand, method_missing and __getattr__)

        Dynamic Dispatch has a very well-defined meaning. It means dispatching based on the runtime type of a variable rather than the declared, static type. The three methods you mention just happen to exist in languages that feature only dynamic dispatch.

        I'm not sure if there's a formal term for the methods you refer to, but they aren't "dynamic dispatch".

    • Woost 15 years ago

      Is there an actual presentation version of it?

      I've tried reading through those slides, but I lose concentration after about the 3rd one because it's too disjointed.

  • cbs 15 years ago

    To rephrase the quote: Design patterns can be good in the appropriate situations, but Java's heavy use of them has soured people on them altogether.

    They're often used ad absurdum in Java, to the extent where even in situations you don't need the complex functionality they support, you're stuck using them (often incorrectly because you don't need them) and they become a burden instead of useful.

    • shepmaster 15 years ago

      In addition to your point, when writing in a language like Java, the overhead of writing code makes doing things the right way (in this case, using a design pattern) harder.

      Steve's example of the Strategy pattern is a good example of this. Contrast using this pattern in C (function pointers), in Java (inner anonymous classes conforming to an interface) and in Ruby (a block).

  • peteretep 15 years ago

    Design Patterns are names given to ways of doing things, so that programmers can talk about the same things.

    Any time you forget that, or start using phrases like 'Anti-Pattern', you lose (unless you're an expensive consultant, then you're about to get paid!). This appears to be the current forefront of Java development methodology (based purely on what I've read on HN).

adgar 15 years ago

Actually, come to think of it, Djikstra [sic] wouldn’t even write any code, because it’s beneath him, but you get the idea.

This is ridiculous. Of course Dijkstra wrote code. He authored the first implementation of an ALGOL 60 compiler, if I'm not mistaken.

Though, technically for Dijkstra writing code was a bit beneath him, as he preferred deriving it using his Guarded Command Language. But the point stands. Dijkstra may have been a bit of a dick, but there's no need to libel a dead man.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection