Live data from Hacker News

"DCI" in Ruby is completely broken

tonyarcieri.com

21–30 of 67 posts

Re: "DCI" in Ruby is completely broken

#21
post #8

I'm not a Ruby programmer, so maybe I'm misunderstanding the article -- are we talking about changing an object's class hierarchy after it's already been instantiated and then complaining that it's the performance aspect that is pathological? That sounds like a completely insane way of writing software to me.

It isn't so odd in Ruby. Ruby has always been a duck typing land. If it quacks, it is a duck. There's even a method missing handler so you can respond to any method call whatsoever. People can and do add methods directly to even built-in classes as well, the equivalent of modifying the class prototype in Javascript. So method calls are considered more messages in Ruby and saying a class will respond differently to a message after it has more data about what it is, a certain blog for example, isn't so strange to Ruby programmers.

Re: "DCI" in Ruby is completely broken

#22
DCI is a paradigm related to design and architecture. Computers are so fast today that does this benchmarking business really matter?

If DCI helps to keep your code maintainable, readable, and less buggy, is that a better tradeoff? I would think that 95-99% of the time, the answer is yes.

On a side note, if speed is mission critical, then would ruby really be the language of choice to use?

Re: "DCI" in Ruby is completely broken

#23

The title of the post is unnecessarily inflammatory. It should be "Using extend to do DCI in Ruby is completely broken." The author even admits this in the article, and points out other ways of doing DCI in Ruby.

What titles are NOT unnecessarily inflammatory nowadays?

Re: "DCI" in Ruby is completely broken

#24
post #8

I'm not a Ruby programmer, so maybe I'm misunderstanding the article -- are we talking about changing an object's class hierarchy after it's already been instantiated and then complaining that it's the performance aspect that is pathological? That sounds like a completely insane way of writing software to me.

That's something that happens a lot in the JS/nodejs world too. It has the potential to be disastrous if you're not rigorous, that's for sure. But it still enables very concise and maintenable code.

Re: "DCI" in Ruby is completely broken

#25
post #8

I'm not a Ruby programmer, so maybe I'm misunderstanding the article -- are we talking about changing an object's class hierarchy after it's already been instantiated and then complaining that it's the performance aspect that is pathological? That sounds like a completely insane way of writing software to me.

It depends.

Is your app CPU-bound? If so, then DCI probably isn't a great idea for you. In fact, building it in Ruby may not be the best idea.

But if your app is IO-bound (like most Rails apps), huge and it takes new developers weeks to get up to speed, then the gains from having a simple, modular code-base should save you developer-time (and hence salaries), which are much more expensive than CPUs.

Having said that, I tend to use SimpleDelegator instead of dynamically injecting stuff into objects.

EDIT: added 'ruby not being the best idea if CPU bound'

Re: "DCI" in Ruby is completely broken

#26

I was curious what Tony's graph would look like using a SimpleDelegator as he suggested. (using ruby 1.9.3p194) Calculating ------------------------------------- without dci 68507 i/100ms with dci 24409 i/100ms with delegator 46945 i/100ms ------------------------------------------------- without dci 2240202.4 (±3.2%) i/s - 11235148 in 5.020463s with dci 412445.3 (±3.7%) i/s - 2074765 in 5.037113s with delegator 1018…

I took a stab at separating out the method dispatch costs from the cost of the #extend call here https://gist.github.com/4436640. I also tried making a call against an unmodified instance of a completely different class to demonstrate that the global method cache is indeed flushed in MRI by doing a runtime #extend on any object instance.

Subtracting the results of different runs like this is pretty questionable, though (the errors accumulate), so the above is to be taken with a pinch of salt.

Re: "DCI" in Ruby is completely broken

#27
post #8

I'm not a Ruby programmer, so maybe I'm misunderstanding the article -- are we talking about changing an object's class hierarchy after it's already been instantiated and then complaining that it's the performance aspect that is pathological? That sounds like a completely insane way of writing software to me.

This also has a precedent in Lisp, see change-class: http://clhs.lisp.se/Body/f_chg_cl.htm

There's even a protocol for notifying instances that their class has changed so they can make any necessary adjustments: http://clhs.lisp.se/Body/07_bb.htm

Re: "DCI" in Ruby is completely broken

#28
I thought the same thing when I came across the DCI pattern. It is very useful for beautifying and simplifying use cases that span lots of objects.

I do something slightly different. I create a class directly for the context and then fire an object into it.

class TheContext def initialize # ... end

  def execute(the_object)
    # ...
  end
end

Re: "DCI" in Ruby is completely broken

#29
You know, I've been thinking about this kind of thing lately. All of this mixin, traits, monkey patching hoopla is completely nonexistent in functional programming languages. To add a new method to an object you just..write a function that takes that piece of data.

Imagine a language where a call looked like this:

    user.doSomething(1, 2, 3)
But it's just syntax sugar for this function application:

    doSomething(user, 1, 2, 3)
("user" would be just the data..like a struct type thing)

That way you get the flexibility of loose functions but you get the (imo) superior aesthetics of oop languages.

Re: "DCI" in Ruby is completely broken

#30
In practice, we've been using DCI (with object.extend) in a production Rails app and have seen no worse performance degradation than in other apps with comparable complexity (at least subjectively--of course it's very difficult to measure objectively). Typically plenty of production apps suffer more from simple things like missing an index on a db column, N+1 queries, iterating over objects in Ruby, or poorly-thought out design. DCI in Rails is a pretty good trade off for when you need to use it.
Post reply on HN