raganwald
(This is a snapshot of my old weblog. New posts and selected republished essays can be found at raganwald.com.)

Tuesday, April 15, 2008
  Dear Raganwald: How do I...


Dear Raganwald:

I love the andand gem you posted, and I have been using it on all my projects. It really does help make the code easier to read because it focuses on what I am actually trying to do and not on the bookkeeping of writing extra if statements and superfluous local variables just to handle nil checking when it is really an edge case.

How can any one argue with Person.find(...).andand.name? Fabulous!!!

And when I am writing my own project, I simply laugh at the doom-and-gloom naysayers who howl about open classes leading to conflicts. andand doesn’t change any object’s existing behaviour, it extends it, in the sense that your post about Strict Liskov Equivalence talks about subclasses extending superclass behaviour and not redefining it. Cool. It’s easy to use something like andand on a project and not screw things up. It just takes a modicum of common sense rather than a slavish fear of what-we-do-not-understand.

Ok, now I have one question. I am sorry to write, but I couldn’t find the answer in the docs. Quite simply, how do I use andand to write a gem, or a library, or a Rails Plugin, or anything else that I have to share with other people?

How do I use andand to write a gem, or a library, or a Rails Plugin, or anything else that I have to share with other people?
—Stan

You see, I like andand but I don’t want to force my opinions on the people using my stuff. So for example, I have this great idea for a Ruby Gem that adds syntactic metaprogramming so that I have an answer for the Ocaml and Lisp folks when they sneer at question Ruby. But while I desperately want to use andand to write the gem, I am worried that perhaps the people who use my gem don’t want to install andand into all of their work? Perhaps they will be annoyed if they discover that I have extended the Object class?

You know that this is innocuous, and I know that this is innocuous, but perhaps they want to pick and choose their own way of handling nils? Perhaps—misguided though this may be—they don’t want Object altered in any way, no matter how much safer it is to extend rather than modify it?

Or maybe they like andand. A lot. And maybe it’s worth it to them to figure out what it does and decide it’s a great addition. But if every gem they install installs one, or two, or even three things like andand, at some point they will throw their hands up in the air and yell, “Enough!” Decisions about projects should always be made with a certain perspective, I think you have said that yourself in some of your essays about time management. It seems wrong to force the people who use my code to decide whether they want andand in their project when they have to decide whether to install its dependencies.

So. How do I use something like andand without forcing it downstream on the people who use my code?

Thanks in advance,



Signed,
Your biggest fan,
Stan.

p.s. I hope you can answer this, I’m sure the answer will also be interesting to people working on large teams who want to use something like andand but do not want to go through a big bureaucratic process getting the entire team to agree that it should be pervasive across the project. If you can use something like andand in one place without changing Ruby globally, that will make a lot of people happy. —Stan
 

Comments on “Dear Raganwald: How do I...:
I'm pretty sure that if you're installing a gem that adds syntactic metaprogramming, you're going to be comfortable with a method being added to Object.

As far as having a bunch of gems that might step on each other's toes, I think we've got two tools that we can use to combat problems: thorough testing and open source. If we install code that screws up our app, our tests catch the problem. Then we can examine and modify the offending code (pre-existing, new, or both - whichever is more sensible), so that it works in our project.
 
Dude. Are you accusing me of sneering at Ruby? If so, that's pretty harsh. If not, then never mind, I'm probably just getting sensitive about the two of us misunderstanding each other.

Ruby scares the crap out of me (more over in this comment thread), but I hardly sneer at it. Ruby is based on the philosophy that more rope always outweighs the fear of hanging yourself, and given that philosophy, it's the best language I've encountered. And the community rivals Perl and Java, which is pretty impressive considering its limited adoption.
 
Robert:

Take it up with Stan!

Just kidding, I was trying to be light-hearted with this one… If you’s offended, I can ask Stan to reword it ;-)
 
Nah. It's fine. Just wanted to be sure, mainly because I spent a lot of time and effort into making sure I didn't fall into the trap of "Your typing sucks, my typing ROXXORZ!!!" It's surprisingly hard to avoid that in the blogosphere, doubly-so because the written word conveys a lot less meaning than spoken.

I was really going for a constructive conversation with that post, so it would have been sad if it came across differently. (I did leave myself one little dig, but I'll leave it as an exercise to the user to figure out what it was.)
 
Robert:

Lose no sleep over it! I suspect Stan was actually inspired by your excellent post to think about some of the consequences of open classes being the “Global Variables of the new Millennium.”

As he puts it, he is comfortable with extending andand in a certain context, but is pointing out that there are some circumstances where you need to think carefully about things.
 
That Stan's a sharp guy.

Nice that he changed his wording, too. :)
 
First, if you're programming in Ruby, you should understand that useful extensions like #andand are part and parcel of using such a dynamic language.

I have often thought that it would be useful to document these mini-meta-patterns in one location, and allow gem / library authors to refer to these patterns in their documentation.

For example, in the README of your new gem, you might write:

Idioms/Funky Stuff:
- Uses #andand in place of ... unless @var (see http://www.metapatterns/andand or http://raganwald.com/...)

Also, remember that as long as you only extend classes without changing any existing behavior, users of your library don't even need to know of #andand's existence (unless they read your code, at which point they should understand the idiom anyway.)

#andand is useful, but is by no means mandatory. If a large team decides that they want to use it, they can add it to their personal list of idioms they embrace. So as long as you provide a clean public interface, and don't make any actual changes to existing functionality in the object space, you shouldn't have any problems.
 
I have run into something similar to this though. We use a modified version of prototype.js (really trimmed down to just provide ajax and a few niceties like the $() function)

We embed this in our site header because there is some registration stuff in there that uses it. Well, some developer wanted to use a widget that uses jQuery.

The problem is that jQuery also has a $() convenience function that is incompatible with the one from prototype. You can't use both frameworks on the same page.. basically he was unable to use his widget.
 
@Sean: jQuery has a nice compatibility mode to avoid problems like this. When you turn it on, it uses jQuery('blah') instead of $('blah'). I understand what you're pointing out here...just letting you know that there's a solution for your particular problem.
 
Raganwald, I've posted about python before, but I've just spent the last week and a half programming in Ruby at my job. So I'm no expert! But! That's kind of the point.

Holy crap would I be confused about what the hell was going on if a random gem I installed put a method into the root object and I used it and then suddenly the project was broken on other people's computers and they were all up in arms about me inventing apparently gibberish code.

Just saying.
 
I personally wouldn't use your gem if it had a dependency on a time-waster like 'andand'. Perhaps that would change if you didn't use such contrived examples, such as:

@phone = Location.find(:first).andand.phone

The phone number you're referencing is scoped to the location, so the chance that you're going to need the location as well is pretty damn high.

You're not saving a local variable, you're just tucking it away in an obfuscated fashion such that 1) anyone unfamiliar with the code will need to spend time working it out, and 2) anyone who wants to extend the code will need to refactor it to use a local variable again.
 
If Ruby had multiple dispatch, it would be completely unnecessary to meddle with Object at all, and it’s not hard to imagine language features that scope resolution to any particular set of multimethods lexically.

(There’s a language long in the works that is supposed to have all that and more…)
 
Nathan:

Your comment supports the question raised in this post quite neatly.

Thank you.

p.s. If you have a strong opinion about andand, may I suggest you comment on a post that is actually about andand? People may want to read what you have to say in a more relevant context.
 
Reginald:

The main reason I posted here rather than on the 'andand' post is that I think it's healthy for developers to play at the fringe of a language (_why, for example). Your andand is interesting and clever, but that's where it ends for me.

So when it comes to taking it out of the playpen and into the real world such as releasing libraries which depend on playpen-style monkey patches, that's when I start to have issues. I lump andand into the same category of code which uses Hpricot's document/'.cssclass' syntax instead of document.search('.cssclass'). It just gets in my way.
 
Nathan:

Your comments veer from what is germane to this post and what is not. As I said, your opinion of andand ought to be posted on the post about andand.

People considering andand for their own projects are going to go to that post to learn about it and decide whether it is right for them. It is unlikely they will come to this post. Why hide your personal opinions here?

Now to the point that is germane, namely the downstream impact. If Library “L” used Gem “G,” the question at hand is whether users of L should be infected with G, whether their code is affected by G.

Your comment is not clear on your opinion of this point. In the case of Hpricot, you saying that you don’t like the code of Library L to use a style you hold in contempt? Or are you saying that Library L exposes this style in a way that forces you to change your code?

This is an important distinction. This post is about gems having an impact on downstream code, not about the impact on code that willfully uses them.
 
> So. How do I use something like andand without forcing it downstream on the people who use my code?

Oh, easy. You wait for Matz to implement selector namespaces. Heh...
 
Reginald:

I must be a bit dense, because I still don't get it. I don't believe that trolling has any virtue, but I'm starting to think that my comments will be seen as trolling since I keep saying the same thing over and over again. I hope you realise that's not my intent.

Anyway, as you said your post is about the "downstream impacts" of a gem such as andand. You've used the example of fellow named Stan, so I'll stick to that.

Let's say Stan releases library S with andand marked as a dependency. I stumbled across S, think that it would save me some time so I decide to include S & andand in my code. As you probably already know (and contrary to futuristic dreams of people like Noble & Biddle), more often than not I'll need to read & modify the code of S. Given that Stan gained a great deal of pleasure from using andand, his code (the code I need to edit) is riddled with it.

When I include third party libraries in my code, they become my code. I use them, I maintain them. You seem to be making the assumption that libraries never need to be touched by those who use them. My experience says otherwise, so I appreciate libraries that use standard conventions.
 
Nathan:

The idea that the style of a library or gem’s code is important to a downstream user because they may need to read it and/or modify it is certainly a different point than the one “Stan” raises.

Does it happen more often than not? I’ll take your word for it that it happens more often than not for you. Likewise, you and only you can decide what constitutes acceptable style in a library that you anticipate using in an intimate manner.

Debating what constitutes an acceptable Ruby idiom—or even whether such a thing is possible to define—is clearly a subject wildly off-topic for this post, so let’s not do that.

p.s. I find that if I believe A if B to be true, it is enough to write A if B. I do not write A if B, and A if C, and D if B just because A if C, and D if B are also true.

My experience with readers is that most of you can readily distinguish between A if B and A iff B. Some are not sure whether I mean A if B or A iff B and will ask. And some will assume that even though I wrote A if B I must have meant A iff B.

You seem to be in this third group from your comment that I am making assumptions about a subject that never arose in this post.
 




<< Home
Reg Braithwaite


Recent Writing
Homoiconic Technical Writing / raganwald.posterous.com

Books
What I‘ve Learned From Failure / Kestrels, Quirky Birds, and Hopeless Egocentricity

Share
rewrite_rails / andand / unfold.rb / string_to_proc.rb / dsl_and_let.rb / comprehension.rb / lazy_lists.rb

Beauty
IS-STRICTLY-EQUIVALENT-TO-A / Spaghetti-Western Coding / Golf is a good program spoiled / Programming conventions as signals / Not all functions should be object methods

The Not So Big Software Design / Writing programs for people to read / Why Why Functional Programming Matters Matters / But Y would I want to do a thing like this?

Work
The single most important thing you must do to improve your programming career / The Naïve Approach to Hiring People / No Disrespect / Take control of your interview / Three tips for getting a job through a recruiter / My favourite interview question

Management
Exception Handling in Software Development / What if powerful languages and idioms only work for small teams? / Bricks / Which theory fits the evidence? / Still failing, still learning / What I’ve learned from failure

Notation
The unary ampersand in Ruby / (1..100).inject(&:+) / The challenge of teaching yourself a programming language / The significance of the meta-circular interpreter / Block-Structured Javascript / Haskell, Ruby and Infinity / Closures and Higher-Order Functions

Opinion
Why Apple is more expensive than Amazon / Why we are the biggest obstacles to our own growth / Is software the documentation of business process mistakes? / We have lost control of the apparatus / What I’ve Learned From Sales I, II, III

Whimsey
The Narcissism of Small Code Differences / Billy Martin’s Technique for Managing his Manager / Three stories about The Tao / Programming Language Stories / Why You Need a Degree to Work For BigCo

History
06/04 / 07/04 / 08/04 / 09/04 / 10/04 / 11/04 / 12/04 / 01/05 / 02/05 / 03/05 / 04/05 / 06/05 / 07/05 / 08/05 / 09/05 / 10/05 / 11/05 / 01/06 / 02/06 / 03/06 / 04/06 / 05/06 / 06/06 / 07/06 / 08/06 / 09/06 / 10/06 / 11/06 / 12/06 / 01/07 / 02/07 / 03/07 / 04/07 / 05/07 / 06/07 / 07/07 / 08/07 / 09/07 / 10/07 / 11/07 / 12/07 / 01/08 / 02/08 / 03/08 / 04/08 / 05/08 / 06/08 / 07/08 /