One of the things I love most about Ruby is the simple extensible ways you can manipulate objects. So when I recently came across a new instance of this, I thought I'd pass it along to my readers. I decided to write a framework for working with pen and paper games, and when I started writing the dice rolling class I noticed that I had a block that had to be unnecessary in Ruby.
num.times { rolls << (rand(dtype)+1) }
sum = 0
rolls.each do |r|
sum += r
end
The first line is just rolling the dice a specified number of times and loading them into the rolls array that I previously declared. The rest of it is just adding up all the numbers to return a sum. Being a former Java programmer this is exactly how I would have done it there, so I just wrote it that way and moved on. But as I began to look back, I realized that it was quite ugly. Beyond that, I couldn't believe that Ruby wouldn't have a more elegant way to handle this common task of reducing an array of components to a final result. Fortunately it does, and the answer is in the inject and reduce methods.
These two methods appear to be identical as far as I can see (if I'm wrong, then feel free to correct me in the comments and I'll edit this later), so I'll be addressing just reduce, since I find it more pleasing syntacitcally. So using these how can I solve my problem?
rolls.reduce(:+)
One tiny line. I love me some Ruby. Reduce actually performs an identical operation on each element of the array, keeping a carryover variable as it does so. For simple mathmatical operations, you can pass a symbol of the operator you want to use, like :+ to add everyone up. But you can also use other operators, even :** if you wanted the code to exponentially increase on every iteration. However, what if you have an array of strings you'd like to get specific data out of with a constant operation. Or what if you want to do a little more complex operation to each one. Well as usual, blocks come to the rescue.
rolls.reduce { |total, n| (total + n) * -1 }
rolls.reduce { |highest, n| highest > n ? highest : n }
The first one does a more complex operation, multiplying the result by -1 every time. It's contrived, but it shows how you can give the array a block of more complex math. The second example iterates through the array comparing the elements looking for the largest item in the array. It should be noted that the return value from the block becomes the new carried variable, and the final returned variable is the return from the method. Also note this doesn't change the value of the array.
Hopefully someone else will find that this saves them some time later!
Specifications are probably the most important, completely ignored artifact I've seen in the developer world. Open source developers (including myself) swear by them, because they are a way to keep us all following the same rules. Yet, for a variety of reasons, they take a long time to adopt, and large companies have a tendency to just run over them whenever they become inconvenient. Worse yet, even when the specifications are revised later to make them work better, they continue to ignore them because now they have a backlog of code that ignores the specifications to work off of (See Internet Explorer). All this brings my latest cause of depletion of my Excedrin bottle.
OAuth is a specification for authentication between applications and server-side APIs. It's supported by most major internet APIs, though most of them are preferring OAuth 2.0 (Facebook recently forced all developers to move their applications to OAuth 2.0). You can find the OAuth specification here.
So why am I writing about this particular specification? Well recently I was working on a few outstanding issues on the ruby twitter gem (specifically Issue #161), which detailed a problem wherein posting a multi-part form with extra options in the body was causing an incorrect signature error to come back from Twitter. I sat down and traced it back to the generation of the OAuth signature in the middleware used by the twitter gem. I realized that it was throwing the entire body in the signature, except for the uploaded media. So I flipped open the specification and found that per section 3.5.2, the body should only be encoded if the content-type is set to "application/x-www-form-urlencoded". So I updated the code, made sure all the test cases ran, verified that it fixed the original problem, then checked to make sure that a few other commands were still working, then called it a day. However, upon review, @sferik discovered that this patch to the middleware had broken the normal status updating function.
Needless to say at this point I felt quite embarrassed, and doubly committed to actually fixing the issue appropriately. So I started going through twitter's development API to check how they were doing their authentication specifically. It was there I found out that Twitter encodes the entire body if there is no uploaded media, and NONE of the body if there is uploaded media. Obviously this is completely off specification (though I'll admit it is more secure than the specification way of doing it). I talked to the guys who run the twitter gem and ended up coding up a custom solution for the twitter gem to override the middleware's OAuth implementation, which resolved the problem.
But in the end I find myself conflicted about the entire experience. I understand that in order to facilitate a more secure environment for their users that the Twitter devs would want to encode the entire body for the majority of their interactions, however by going off specification, they're making it more difficult for all the other developers by forcing everyone to use custom solutions to deal with them. And anyone who's ever worked with CSS in Internet Explorer knows what kind of headache that can be.
So I guess in the end I'm curious what you all think? When is it appropriate to ignore the specification and code your own custom solution? Is it whenever you can do it better? When your company is large enough? When it threatens your clients? What's your tipping point?