Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Thursday, October 21, 2010

One hour from now...

So, I'm a long-time Java guy, wading into Ruby/Rails and really liking it so far. I know most of you who have made the transition are already aware of how much nicer many things in RoR-land are, but I thought I'd start just collecting a series of posts on my own personal findings. Just 'cause.

Case in point, this morning I was writing a unit test in Java, and needed to use two dates in my test code, one that was further in the future than the other. In Java, this looks something like this:


Date now = new Date();
Calendar calendar = new GregorianCalendar();
calendar.setTime(now);
calendar.add(Calendar.HOUR, 1);
Date oneHourFromNow = calendar.getTime();


I know I don't need to explicitly set the calendar to 'now', however, I use the 'now' reference in the tests, so it seemed to be slightly more correct and explicit to do so. Further, the only reason for this setup code is to use the now and oneHourFromNow references in my tests.

In Rails, I would simply reference:


Time.now


when I wanted to get the current time, and then use the nice time-related functions that Rails adds:


Time.now + 1.hour


when I needed a time that was in the future. If I wanted the exact same semantics as the Java code, I suppose I could do this:


now = Time.now
one_hour_from_now = Time.now + 1.hour


but that doesn't seem to add much in the way of comprehensibility, so I'd likely skip that altogether.

So, in reality, what would take me five lines of code in Java, essentially takes zero in Rails, which, as I calculate things, is infinitely better.

Monday, January 26, 2009

TDD in Space

I don't know about you, but I find some aspects of test-driven development hard. Too often I'll find myself writing trivial unit tests, typically revolving around persistence or login. I mean, really, should you be spending time writing tests to ensure your application's persistence layer is functioning correctly? That should just be a given!

However, I've been pushing through my initial hurdles, and am really starting to see some solid payback. One of the unexpected benefits is that my API almost immediately becomes more readable. Not convinced? Think about it. In test-driven development, because you're writing the tests in "problem brain-space" instead of "solution brain-space", you're thinking in terms of the problem that needs to be solved, not how you're going to solve it.

While you're in "problem brain-space", you're in the same sort of place that users or maintainers of your code will eventually find themselves in. There are many possible "solution brain-spaces", each with their own set of unique concepts and terms, but typically in the "problem brain-space" you're more likely to be speaking a common language. Which is a good thing.

Friday, October 31, 2008

Thinking in Git

I recently started using Git on a small team project. Why Git, you ask? Well, previously I had used CVS and Subversion (and by such admission I am knowingly submitting myself to being mocked by Linus), and prior to that had used Visual SourceSafe. So I figured it was time to learn something new and dive into distributed version control.

I have to say, it's a bit of a leap. In the same way that I stumbled through learning to trust in CVS to merge my changes, as opposed to locking a file the way SourceSafe did, I'm finding the distributed model takes some getting used to.

It's great that I don't have to have network access to do commits. That's the easy part to appreciate. With Git, you commit to your local repository copy. If you want to bring your changes together with someone else's, either you push to their repository, or they pull from yours, but that is in no way tied to the act of committing your changes. There's no built-in notion of a master repository. Really.

For some reason I'm finding it difficult to grasp that concept. For years I've relied on the notion that all my changes are safely locked away in the master repository. The master repository is the source of all truth. (Ha ha, get it? "Source" of all truth? You don't get it. Fine.)

In our particular team setup, we do have a master copy hosted on GitHub. I'm finding that every single time I do a "git commit", I have this unstoppable compulsion to execute a "git push", and I'm not sure that's the right idea. I'm looking forward to that breakthrough moment when I finally get it. I'll let you know when that happens.

Wednesday, August 20, 2008

From the "things I wish Java had" file...

Often you'll find yourself writing code similar to the following:
String childName = root.getChild().getName();
Now, if root.getChild() returns null, you'll get a dreaded NullPointerException. There are a couple ways to guard against this of course, but they're fairly verbose. You could check each traversal point for null...
String childName = null;
Node child = root.getChild();
if (child != null) {
childName = child.getName();
}
That works, but it gets messy quickly if you have another traversal or two (and yes, I know, excessive depth is a bad code smell).

Alternatively, you could do something like this:
String childName = null;
try {
childName = root.getChild().getName();
} catch(NullPointerException ignored) {
}
But you could really end up littering your code with ignored catch blocks.

Ideally, I would love to have a method of saying "traverse as far as you can, but return null if you encounter null along the way". Perhaps a special operator?
String childName = root,getChild(),getName();
Anyway, I'm sure there are languages out there that support this notion. It's high on my list of desired features for an alternative to Java!