On Sun, Feb 24, 2008 at 06:07:36AM +0900, Avdi G. wrote:
Hi folks,
I wrote a blog post with the intentionally provocative title above,
which can be found here:
http://avdi.org/devblog/?p=18
[…]
My hope with this post is to start a conversation about fostering
robust software extension mechanisms in the Ruby ecosystem. I welcome
any comments, both here and on the blog.
I read the post. I think it is both futile and wrongheaded. Futile,
because
I don’t think it will change anyone’s opinion. Wrongheaded, because I
think
it’s a filtering problem rather than an approach problem.
For any community of open source software, there will be lots of code
released. A lot of it will be crap. Consider CPAN; it’s full of
implementations and reimplementations of the same APIs, functionality,
and
bindings to C libraries. Some of the packages are good, but a lot of
them
are crap. How do you tell the crap from the good? That’s a filtering
problem. Trying to get people to only release good code is utterly
futile.
So you had a problem with UnitRecord. Its code smelled bad to you. You
reimplemented the functionality in NullDB in a way that doesn’t smell as
bad. Assuming it works equally well (I haven’t had occasion to use
either),
there are now two implementations of the same functionality, one of
which
is, for some metric, better than the other. Should the worse one never
have
been written/released? What a silly thought. Even if it shouldn’t have
been, there’s no means to control it (nor should there be, in my
opinion).
Furthermore, would you have thought to write your “better”
implementation
if the “worse” implementation hadn’t been there as an example? Maybe,
maybe
not.
There’s an argument, usually in the context of test-driven development,
for
doing the simplest thing that works. Well, you say, it doesn’t work. No,
it
no longer works for your purposes. That’s when you need to revisit it.
If
a piece of code implementing functionality you need is causing problems,
you need to either fix it or find/build a new implementation of that
functionality.
Monkey patching can cause problems, but it makes it easy to get things
working quickly. There’s a lot of value in that. Until it breaks, it’s a
win. When and if it breaks, it’s time to fix or replace it. This is true
of
any number of other techniques (e.g. relying on Rails-generated SQL
until
there are performance problems).
So don’t lament that people are using this tool to increase their
productivity, and that it sometimes gets in the way of your productivity
when you reuse their code. Rejoice that someone thought of useful
functionality and implemented it for you, and fix/replace it if it
doesn’t
suit your needs. If you are dedicated to never releasing code that
includes
monkey patches, more power to you. Don’t expect anyone else to follow
that
lead.
As a side note, I had a knee-jerk reaction to ignore the entire post
when
you brought up dependency injection and robustness. It shows a very
enterprisey (in the worse possible way) perspective. You and your team
were
capable of figuring out and fixing your problems. Your reaction to a
hard
problem should not be to promote “practices” to make it easier for less
capable programmers; it should be (as it was with NullDB) to solve the
problem and release your solution for everyone’s benefit.
Avdi
–Greg