At Mobile Commons, we have to write a lot of code under time constraints. We also work on a fairly distributed basis, which means that writing readable code is not a luxury, it’s a necessity. We can’t afford to be clever for clever’s sake, but if a new idiom helps make our code easier for our colleagues to grasp in a hurry, we embrace it. Here’re some idioms we’ve recently created:

Object#andand

Ruby programmers are familiar with the two guarded assignment operators &&= and ||=. The typical use for them is when you have a variable that might be nil. For example:

@first_name &&= @first_name.trim@phone ||= '612-777-9311'

You are trimming the first name provided it isn’t nil, and you are assigning ‘612-777-9311’ to the phone if it is nil (or false, but that isn’t important right now). The other day we were discussing the guards and we agreed that we wished there was a guarded method invocation operator. Here’s an example of when you would use it:

@phone = Location.find(:first, ...elided... )&&.phone

Meaning, search the location table for the first record matching some criteria, and if you find a location, get its phone. If you don’t, get nil. (Groovy provides this exact functionality, although Groovy uses ?. instead of &&.) However, &&. won’t work because &&. is not a real Ruby operator. So what do we write instead?

A feature is “powerful” when at least one of the following holds:

It can be used to implement something trivial in an pointlessly complicated way.

It can cause a lot of damage.

Seriously, it seems like 85% percents of the contexts where something is called “powerful,” it really means “useless and dangerous.”

Note that we need a local variable to make it work without extending the Object class. Note further that although we only need the local variable for one line of code, it is in method scope and we must be careful that we don’t clobber an existing loc variable. And when reading this code, we now have to look and see whether loc is used again to understand what this line does.

This is a scoping problem. if you are going to use variables, you want to restrict their scope as much as possible. It feels like half of what we do when programming is manage side effects like overwriting a variable you are using elsewhere, and the more you can restrict those side effects, the easier programming becomes. Java supports block scoping natively, and languages like Scheme solve this by providing a block scope macro, let. And you can roll your own in languages like Javascript that provide anonymous functions. But this seems to get the natural left-to-right order wrong:

Well, we are tinkerers and toolsmiths. So let’s roll our own. We can’t use &&. without rewriting the Ruby parser, and that seems drastic. So let’s use “andand” in the hope that our non-English-speaking colleagues will forgive us. We want to write:

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

And get the same effect as @phone = ->(loc){ loc && loc.phone }.call(Location.find(:first, ...elided... )). This would be bloody trivial if we have a macro facility, but “If wishes were horses then beggars would ride.” Instead, we need to write a method that does some conditional evaluation for us. If the receiver (in this case the result of Location.find(:first, ...elided... )) is truthy, like an ActiveRecord model, we want andand to return it so we can use it. But if it is falsy, we want andand to somehow return something that takes any message you send it and returns itself without doing anything. In other words, we want a mock object of sorts. So that’s what we’ll do:

Actually, there is more to it than this, for example the MockReturningMe class is enclosed in a module to minimize namespace pollution. Consult the source and RSpec (links below) for the latest particulars.

Note that because you accept any method using Ruby’s method invocation syntax, you can accept methods with parameters and/or blocks:

Some of the other solutions to this problem that use send change Ruby’s syntax. This solution emphasizes syntactic regularity: the goal was to make an “&&.” operation that worked like &&=. &&= looks just like normal assignment, you can use any expression on the RHS, only the semantics are different. The andand method also works just like a normal method invocation, only the semantics are modified.

Both return the location, not whatever happens inside the block. This is very useful, especially when chaining methods in a pipeline. Sometimes you want to do something for side effects, but continue on with the chain. For example:

This is much nicer when you are “injecting” some extra code into the middle of an expression, such as when adding some poor-man’s-debugging puts statements.

Would we ever want to go beyond a block and write Location.find(:first, ...elided... ).tap.some_method instead of Location.find(:first, ...elided... ).tap do ...elided... end? Of course we would! Quite often, we want to send several methods to the same receiver. In Smalltalk, the semicolon does this explicitly. In Ruby, we have to be very careful to make sure our methods return self to enable chaining. For example:

[1, 2, 3] << 4 << 5 => [1, 2, 3, 4, 5]

But if a method doesn’t return the receiver, chaining doesn’t work. That’s why we had to use “returning” in the array example above:

When you examine the source, you’ll see that tap looks a lot like andand. No surprise, we are doing similar things with slightly different semantics.

This implementation of Object#tap has two advantages over the implementation in Ruby 1.9: first, it works in Ruby 1.8. Second, it adds the ability to call another method (like pop) and not have to include a block.

Summary: andand & enhanced tap

andand and tap both provide the same two benefits: First, they either eliminate (in the case of a method call) or limit in scope (in the case of a block) a local variable. Second, they let you maintain a natural left-to-right order when writing pipelined expressions. They are simple and obvious enough that I feel any unfamiliarity for the reader will be more than outweighed by the cleaner, easier-to-digest code that results from their liberal use.

My suggestion is that these two benefits make it worth your while to add these methods to the Object class and use them regularly in your code.

I have now seen two people asking about using an inline rescue instead of andand:

Location.find( …elided… ).phone rescue nil

Also, one of the alternate solutions seems to use this technique. Obviously, it works for many of the cases you want to try, and you don’t need to add a new method to Object. However, it is—to paraphrase Chalain—“Sneaking up on the Interpreter.”

It achieves what we want almost by accident, namely that it rescues NoMethodError, which by coïncidence gives us the result we want. However, it does not communicate our intent. It says that we want to transmute all exceptions into a value of nil. When someone glances at the code, will they think of NoMethodError? Or will they assume that we are trying to handle exceptions that the .phone method might throw?

And what if .phone actually throws something serious? In Rails, what happens if a migration is screwed up and there is no phone column? I think we actually want a NoMethodError in that case. The rescue clause will accidentally swallow the exceptions we are trying to catch.

I think if you are absolutely certain that you do not care about other exceptions and also if your team uses this idiom extensively so that it does not miscommunicate its intent, you can live a long and happy life using it. However, I would be hesitant to recommend it as a general-purpose solution. andand and some of the other solutions obviously require the code reader to learn a new method name, but after that they offer the exact functionality we need and clearly communicate their intent.

I was able to produce the desired effect simply with the following code...

Are you able to write (expression...).andand.phone?

Are you able to write (expression).detect {...}.andand.inject(42) {...}?

There are a lot of very simple things you can do if your needs are limited to sending a message that has neither parameters nor a block. If you wish to be able to use andand anywhere you would use a normal method invocation, with as little deviation from the normal syntax as possible, you may want to consider andand.

This is a great idea for making Ruby better! However, this is merely a special case of a monad, which can be used for many more powerful applications, especially in purely functional languages. It would probably be better to implement a true monad system in Ruby rather than something with only a few uses.

Ruby is a multi-paradigm language, borrowing ideas from Perl, Lisp, and Smalltalk. By all means write a general-purpose Monad feature for Ruby, it can go alongside of things like unfold and lazy evaluation.

However, I would stop a good ways short of saying that a full Monad implementation would be better. Language features embody trade-offs, and implementing Monads (with andand being the Maybe monad) involve a different set of trade-offs.

One of the things andand achieves is conformity with an existing mechanism for guarded assignment, &&=. If you implement Monads, shouldn't &&= also be implemented as a Monad?

Which leads to implementing = as a Monad as well. There is nothing wrong with going down that road, however by making different trade-offs you will be creating something that appeals to a different audience.

Good to see you... After the Rocky Horror Picture Show, work was pretty thin for you... until Dark City. But I digress:

I personally would never use an inline rescue like this, it is kind of "sneaking up on the interpreter." It achieves what we want almost by accident, namely that it rescues NoMethodError, which by coïncidence gives us the result we want.

However, it does not communicate our intent. It says that we want to transmute all exceptions into a value of nil. When someone glances at the code, will they think of NoMethodError? Or will they assume that you are trying to handle exceptions that the .phone method might throw?

Worse, what if .phone actually throws something serious? In Rails, what happens if a migration is screwed up and there is no phone column? I think we actually want a NoMethodError in that case.

FWIW, one of the other solutions I linked used a similar scheme, so I may be the only one who rejected this approach.

nah, still, got a biw of work, between that ac/dc thingy and ken loach movie on me..

Anyway, yeah I would not use inline rescue for the general case, but since it's a kind of guarantee that phone is juts ana accessor method, I don't expect it to throw an exception.As for handling serious errors: it's not catching Exception, but StandardError, so a missing migration would not be caught.

Yet, you're right, it doesn't communicate the intent strongly enough, thanks for taking time to answer.

So, the longer answer in my mind is that if_not_nil sounds like an if expression, so I would view it as an if expression that happens to perform a binding in the bargain.

That is very useful. But it still looks a lot like an "if," it emphasizes the conditional.

Should I be writing some code where the nil case is really important, I might use if_not_nil as you suggest. However, if I wanted to invoke a single message and I wanted to emphasize the message and not the conditional nature, I would prefer andand. I think these two statements say slightly different things even though the both produce the same result:

Location.find(:first, ...).if_not_nil { |loc| loc.phone }

Location.find(:first, ...).andand.phone

The "if_not_nil," the block, and the block parameter all add weight to the condition, suggesting we ought to think about it more than we think about getting the phone.

This reminds me of the dwim idiom in elisp, which stands for "do what I mean". It's used when a function should usually, but not always, do what it says it does. For example, rejustify always rejustifies your buffer but dwim-rejustify would fail silently if you ran it on a binary file.

I think "andand" as a term is a little bit opaque, but I can't think of anything less opaque that isn't significantly more bulky. I would have been tempted to call it Object#just_work_dammit or Object#with_your_shield_or_on_it or perhaps Object#pleaseohplease, neither of which has that same zippy and quite pronounceable feel.

My first thought was to recommend Superators, but alas they do not work with logical operators. However, you could maybe craft up some interesting operator like "~~", but Superators may be bordering on write only.

Do put me right if this is an incredibly stupid thing to do, but what about...

class NilClass def method_missing(method, *args) nil endend

You're already extending the Object class so I'm assuming core classes in general is fair game here.

There is one problem that I can see, which is that Location.find(:first).phone will throw a NoMethodError if a Location is found, but will return nil if no location is found (for the case where Location#phone is not defined). Still, I've found it useful for some things.