Ruby has a quasi-convention of taking a method, slightly modifying its behavior, and denoting it with a trailing exclaimation mark, e.g. #select becomes #select!. Sometimes these methods raise an error, modify the receiver in place, or return nil on no-op, or do some combination of these, or something else entirely. Such methods are collectively referred to as “bang” methods, and there’s no hard-and-fast rule for what makes them special—just that they are “more dangerous” than their non-bang counterparts.
Today I’d like to write about bang methods that modify their receivers in place and return nil on no-op, and how you can improve performance in Ruby applications by (ab)using them to reduce object churn in hot paths.
I’ve been experimenting with whole-home audio since college. I bought a 100′ stereo cable and ran it from my roommate’s bedroom all the way down to the front room so we could have music playing on both floors of our four-person townhome. I remember price-shopping multi-zone amplifiers when I didn’t have two nickels to rub together. It seemed the height of luxury to be able to listen to the same song no matter where you were in the house.
Browsers place limits on the number and size of cookies present for a domain or in a response. If you exceed these limits, Bad Things can happen. Rack and Rails try to prevent this in the obvious cases, but this post describes what they get wrong in their current implementations. We’ll also review the potential impact of—and how you can mitigate—this type of issue in your Ruby web apps.
This information is most relevant for web apps that transmit session cookies that contain the encoded contents of the entire session hash—not just the session ID. In other words, a cookie-only session. For example, Rack::Session::Cookie with Marshal or JSON, Rails’ default ActionDispatch::Session::CookieStore, or an implementation of JWT (JSON Web Tokens) that uses a cookie (instead of a dedicated response header) as its transport. The security risks are greatest when cookie-only sessions meet the cookie-truncation behavior of older browsers (and can be compounded when the sessions contain arbitrarily-large data, such as flash messages).
I was working with the official Ruby gem for the Zendesk API. It’s a quirky little thing but on the whole quite nice to work with. I did run into one little gotcha: in order to retrieve all the items in a paginated collection, you have to use the #all! or #all methods (the bang version raises an error), and you must pass it a block.
I’m fiddling with a bit of Ruby code for my silly Ioughta gem. In this module, the each_resolved_pair method takes a structure of “pairs” (of symbols and lambdas) and mutates them (by calling the lambda with an incrementing value), returning the resolved pairs.
I thought I’d write about how fanriff.com serves its Ember.js index from its Sinatra.rb API, and how web clients interacts with the back-end once the application is loaded. It started to run a little long so I’ve broken it up into parts. This first chapter will cover some background information on Ember, the fanriff.com web architecture, and how we deploy our Ember index to our stack.
The slides for my recent Torii for Ember.js Lightning Talk (it ran a little long, so it was more of a “thunder” talk) are now available to download. They closely follow my post about Ember.js and Torii from September, and indeed the slides link to that post for the code walkthrough. Please let me know in the comments if you have any questions, and of course I’m available to chat in the EmberJS Community Slack team as @mwpmaybe (invite yourself here if you’re not already signed up).
I think there’s a video of my talk, but I understand the quality is not that great. I’ll post it here as soon as possible, assuming it’s not too bad.
Every now and then, rpi-update will crash halfway through and completely hose up the boot partition on my Raspberry Pi’s sdcard. To fix it, I have to mount the sdcard on my Mac, repair the volume, and download the firmware bits from rpi-firmware. Here’s that process in a nutshell.
Unfortunately, this doesn’t work in Sinatra, or at least not on Sinatra 1.4.6, Rack 1.6.4, and Ruby 2.2.3. Why? Well, body is (for some reason) an array, so its length is probably zero (nil body) or one. It also occurs to me that we care more about the byte size of the body than its string length; if you think a 513-byte response is worth compressing, 512 characters encoded in UTF-32 (2,048 bytes) certainly is!
Here’s a modified (and code-golfed) version of the above snippet for Sinatra: