Posts

Showing posts from 2015

This One Subtle Bug You Might Not See Coming

Sometimes bugs are obvious. You used a ++ where you should have used a --. Other times, bugs are much less obvious. A regular expression was missing an escape of a .. Then there are those bugs that are so subtle and insidious that they deserve their own blog post just to document and excoriate them. This post is about one of those bugs.

Fortunately for me, this wasn't my bug. It was a bug hidden in a Programmers.SE question. The questioner was blaming himself for not seeing or understanding a change in an external library, and he was desperately looking for a way to write better code to account for such changes in the external library. What did that library do? There was a method that returned a long, where the long was milliseconds since epoch. In the update, the method was changed so that it still returned a long, but the long now represented nanoseconds since epoch.

Putting aside the discussion about whether a long has enough precision, this change is a special type of awful. T…

Moving Sideways with Lateral Abstractions?

When I'm doing design and refactoring, part of me worries that I'm just creating a mess of objects and classes. One of the kinds of mess that I feel I make the most are lateral abstractions. What I mean by lateral abstraction is an abstraction that is at the same level as the code I abstracted it out of. It doesn't add very much to the conversation, and it doesn't introduce a finer vocabulary than was already there. When looking over the code I wrote in Writing a Better Code Narrative, I get a slight feeling in the back of my head that some of that code is lateral abstraction.

Without re-posting all of the code (which can be found here), I started with a CommandParser class that read a string of character commands and "executed" those commands to produce a new output string. The original code was intentionally hairy, but I refactored it down into a series of Command classes to encapsulate the individual behaviors, and a CommandFactory to encapsulate the algor…

Two Great Takeaways from GOOS

I recently just finished reading Growing Object-Oriented Software, Guided by Tests (or GOOS for short) by Nat Pryce and Steve Freeman. I highly recommend every developer pick up a copy and give it a read. It is full of great advice for building a well-tested, high quality application. I wanted to pick out two particular gems I found towards the end of the book that I felt are really powerful.

[W]e like to have names for the relationships between objects as well as objects themselves. As the legends say, if we have something's true name, we can control it.– Growing Object-Oriented Software Guided by Tests, page 244 (authors' emphasis)

They are talking specifically about preferring to mock interfaces rather than concrete implementations, but this concept bubbles up generally throughout the book. They use interfaces extensively, even noting that their use is above average, to tease out concepts and relationships in the code. Many in the community feel that interfaces are just need…

YAGNI vs Refactoring

I am currently reading through Growing Object-Oriented Software Guided by Tests by Nat Pryce and Steve Freeman. It is a great read and I highly recommend it. They describe a methodology for building high-quality software from the ground up, using all levels of testing to ensure that quality and functionality. Early in the book, they cover many concepts that are commonly heard in the developer community, including YAGNI and refactoring. Later in the book, they use a "real-world", messy example to demonstrate their methodology.

At the end of chapter 16, about halfway through their real-world example, something struck me in their observations for the chapter. They are leaving the example in an ugly state in need of refactoring. In their observations, they state:

So now that everything works we can get on with more features, right? Wrong. We don't believe that "working" is the same thing as "finished." … [W]e can either clean it up now, while it's stil…

This 1 Weird Trick to Almost Any Design Pattern!

I was answering a question on Programmers.SE the other day, as I am wont to do from time to time, and something interesting struck me. As I was constructing my answer, I found myself looking for a design pattern to name that would be apropos for the situation (I settled on the command pattern), and while I was grasping for the right one, I thought, I want the one where we put an object in between. It hit me: that's almost all of them!

That's right, nearly every design pattern is basically just "create an intermediate object to encapsulate what you want." For example, we have the command pattern: create an object that calls behavior in the way that we want. We have the adapter pattern: create an object that transforms what we have to what we want. We have the strategy pattern: create an object that will polymorphically perform a behavior we want.

As I realized that, I felt like, while design patterns offer a great way to name and model a certain solution when you need…

Interfaces and the Need to Know Implementations

Many languages provide the ability to create explicit abstractions in the form of interfaces and abstract classes. Other languages don't provide this explicitly, but rely on the concept of duck typing for the same purpose. Either way, we use abstractions to hide the underlying complexity of implementations. Though we may use these abstractions, all too often we don't trust these abstractions.

Often I hear or see developers talking about how they can't use an abstraction because they need to know exactly what type of object they are dealing with. This is especially true when the runtime type is determined at runtime rather than at compile time, since we cannot know what the type might be. It's possible that it is some second- or third-party type that we've never seen, and therefore cannot know how it will work. How could we possibly trust some unknown code that is just stuck into ours?

But do we really need to know the runtime type? The biggest reason I've seen …

Getting Google Cardboard to Work with a Samsung SIII

Image
Recently I received a SunnyPeak Google Cardboard Viewer as a gift. The technology is pretty cool, allowing for any Android device to act as an inexpensive VR headset. There are a number of apps that provide interesting 3-D environments to explore. The challenge I ran into was that Google Cardboard does not work correctly on my Samsung Galaxy SIII. Instead of taking up the whole screen, the images take up only a part of the screen. A simple fix would be to change the settings in the Cardboard app, but Google made life way more "convenient" by allowing the settings to be changed only through scanning a QR code.

After some Googling around, I came across a post where someone else was having the same problem. In the comments, someone had the answer. In short, the comment gives a link to a page to generate a settings QR code, and the settings to put in. After following the instructions, the app configured itself correctly and it worked great!

If you are having the same problems an…

Writing a Better Code Narrative

Writing code is like writing a book in a lot of ways. Like a book, code is read far more often than it is written. Therefore, like a book, code should be written in a way that gives it a clear narrative. By having a clear narrative, one can follow the code and understand it without too much head scratching. There is a lot of code out there that doesn't have a clear narrative. It meanders and backtracks, leading to confusion. One of the biggest contributors to confusing structure is the complex if statement. if's and else's take the story back and forth, and all over the place.

There are many tools in good design to fight the confusing tendencies of complex if's. One that changed the way I write my code significantly is the guard clause. Rather than wrapping a whole bunch of code in a big if, we reverse the condition and return early. Rather than worrying about the condition the whole way down, we can conceptually just eliminate that case as early as possible. Guard cla…

Using .htaccess to Redirect to Minified and Pre-Compressed Assets

Minification and compression of assets (JS and CSS) is a common practice across the Web today. It improves performance by reducing the amount of data that has to be transferred over the network, without changing the behavior of those assets. Because those assets are text, the size reductions can be dramatic, especially when we use both techniques together. Using these techniques, though, is not necessarily transparent.

Generally, minified assets are referred to with a .min.* extension to indicate they are different (thus, minified jquery.js becomes jquery.min.js). Because this convention is in the file name, it must also pass down into our references: <script src="jquery.min.js"></script>. To switch between the minified and un-minified versions, we have to actually change the code in the HTML. Source maps are a different, potentially more robust solution, but require support both in the browser and in build to generate those files.

Compressed assets are even hard…

Learning Rails (So Far)

I've started learning how to use Ruby on Rails for development. I've touched on using Rails before, but I didn't get very far. I'm using the Ruby on Rails Tutorial book as my guide. I'm using the second edition (because I bought it a little while ago), and it is based on Rails 3. Now that Rails 4 is out, doing a gem install rails pulls down that latest version, Rails 4. I could specify a version, but from what I read, the differences between 3 and 4 are fairly minimal for the scope I am dealing with.

I ran through the first demo, which is basically installing and running Rails, both locally and on a remote host. This was fairly straightforward on the local side:

gem install rails
rails new first_app && cd first_app
rails server

The book recommends using Heroku as a remote deploy target, but I already have a web server (on a shared host) that supports Rails, so I wanted to use that again. The shared host provides a simple GUI through cPanel to create Rails inst…

Periscope + Live Coding?

Could Periscope be a great new platform for live coding? Periscope allows users to quickly and simply broadcast anything they want to the world, and this makes it a great platform for experimentation in different forms of use. Live coding could be a great application for the service, allowing for near-instant feedback and interaction.

There would be some challenges to this. Periscope only works on smartphones, and does not allow screen sharing (as far as I know). This means that live coding wouldn't actually involve seeing any code, which would in some ways defeat the purpose. To ameliorate this, a second stream of the screen could be set up on another service, or the code could simply be made available after the fact with a detailed commit history.

On the other hand, Periscope reaches a wide audience, and is very simple to set up and use. The low ceremony means very little distraction from productivity. There are few hassles with the software. A single person doesn't have to …

Trying Out FreeBSD

I've used Linux as my main driver for several years now. I've been quite happy with it, as it does so much to make my life easier. But like so many things in life, sometimes it's best to see if the grass is greener on another side of a fence. Hearing so much about it from Allan Jude on TechSNAP and BSD Now, I decided to give FreeBSD a whirl. I tried it first in a VM, then later installed it to an old laptop to really test out how well it worked.

My goal was to get a full-fledged desktop system up an running, preferably comparable to my Linux system. I knew this was possible given what I had seen and heard. FreeBSD is a UNIX-derived system that looks a lot like Linux. Many of the same programs will run on both, and so it won't "feel" too different. I tried both FreeBSD proper and the desktop spin, PC-BSD, in a VM to get a feel for each. In the past, I had tried to play around with NetBSD, with little success, but I didn't let that experience cloud my opini…

Exposing the War on Design

A long time ago, I watched Sandi Metz' GoRuCo 2011 talk, Less - The Path to Better Design. I really liked that talk, and I felt like I got a lot out of it at the time. She talks about design, and shows how to improve the structure of a piece of code. There were some things I didn't feel like I all-the-way understood the first time around, but it was a really good talk and got a bookmark. Then, one day more recently, I watched the talk again, and I discovered how much I missed the first time around. The ideas about design were much deeper than I originally understood, and those parts I didn't all-the-way understand were suddenly much clearer.

We develop software in a cloud of uncertainty. This is not a failing, but simply a reality. This cloud of uncertainty frustrates us when we try to design our software. It frustrates us so much that we as an industry have taken the argument up a meta-level to a debate about whether we should even try to design, when, and how much. We…

The Visitor Pattern Needs Fixed. Here's How.

The Visitor Pattern is a powerful idiom of object-oriented programming. It has the unique power to break through the type system and recover hidden type, all while using the type system and double-dispatch to accomplish this feat. Through this superpower, it is able to give the impression of adding new behavior to closed classes.

The visitor pattern is very powerful, but it is also quite burdensome. Classes to visit must implement an #accept method that takes a visitor, and then immediately calls that visitor with itself (generally, or some data on itself). This double-dispatch is what allows the type to be recovered, since a type's this will always be its own type. The problem then, is that there is a repetition on all of the different types to visit. Each subtype must implement #accept. It also treads the line of an SRP violation. A class must be concerned with what it does, plus allowing a visitor to visit it.

This really has never sat that well with me, so I began to think abo…

Learning to Refactor Other People's Code Therapeutically

StackExchange's CodeReview site provides a wealth of code samples representing the best, and sometimes the worst, of code that can be produced. It has snippets volunteered from all types of code bases in nearly every language. One could get lost for hours just reading how other people, both posters and answerers, choose to solve problems. It is fun to dive into some of the code on this site and work through refactoring it to see what comes out the other side.

One such example I happened upon recently was this little gem. To summarize, it is a function that builds URLs from parts and puts those URLs into a dictionary object. It is written in Javascript for Node.JS. It uses a recursive function to permute the parts together to use as the dictionary keys, and for building those URLs.

This is one of those pieces of code that fails the Squint Test badly. There is a lot of deep nesting, with fors inside of ifs inside of fors. Given the indentation, the bottom half of the code doesn'…