Null Object Pattern For Avoiding Null Checks
I’ve had it on my todo list for a while to go ahead and look into the Null Object pattern. I vaguely recalled that it allowed you to return a null object and not have to actually test for things like:
if (employee != null && employee.isCurrent()) { employee.promoteOneLevel(); }
I see this all through a lot of java code to avoid the dreaded NullPointerExceptions (NPE). If a Null Object can clean up this sort of thing I’m all for it.
Essentially the trick is to implement a do nothing class like NullEmployee that implements the Employee interface, but all of its methods do nothing. In the case of isCurrent() in Employee, you just have the NullEmployee.isCurrent() method always return false. Pretty simple really.
I’m glossing over the details really and I need to spend a bit of time doing some more implementations. You can find more about it by Bobby Woolf, Martin Fowler, and Joshua Kerievsky.
Rake in Rails Switching InnoDB to MyISAM
About 11:00pm on April 7th I ran
1
|
rake
|
to run all my tests. I had a nasty problem where I went from all of my tests running on the depot sample application in the Agile Web Development Rails book to spitting out tons of errors. It didn’t make any logical sense. The error I saw over and over again was that the first record didn’t exist so the errors looked like:
ActiveRecord::RecordNotFound: Couldn't find Product with ID=1 ... in `products` test/unit/product_test.rb:7:in `setup_without_fixtures`
OK, next step was to just try to run a single unit test, so I jumped back to the
1
|
product_test.rb
|
unit tests. Run the 6 tests, ugghh, 3 of them error out. I know they were working last time I worked on the sample project.
I commented out all but the first test and started adding them back in one by one. After I added more than ones that just checked the initial values they just started failing again. Gheesh!
So, next solution is look at the logs. Not a lot of information there, but the SQL, so I wanted to add logger statements at the start and end of my tests. Took a bit of hunting to find out how to do it, but Robby Russell had a nice explanatory post on Rails, Logger, and Those Pesky Tests.
OK, I have logging, so I can see what’s going on. At this point I feared I was going to find out the order of the tests perhaps mattered and after deleting one entry the next test failed because it didn’t reset the records in setup(). This isn’t really how xUnit frameworks are supposed to work, but I was having trouble seeing the logic of why the tests are failing.
Run the tests, and the same failures. Look at the log, and yes, they are run in random order and each one ends with a ROLLBACK statement. Of course this makes sense, because under Rails 1.0 and up the default is to use transactional fixtures. At this point I decide to look at MySQL and the databases. Aha! The database tables are defined as MyISAM which doesn’t support transactions. I could have sworn they were already defined as InnoDB, but maybe I was confused.
OK, I switch them on the test database and then run rake again. No!!! The same huge number of errors. This doesn’t make a lick of sense. OK, look at the database again. OK, the tables are back to MyISAM. So it turns out rake is automatically using the development database to recreate the test database. So a simple change of the development database to InnoDB tables was in order. Run,
1
|
rake
|
again and all the tests pass.
Time for some sleep.
30 Day Software Trials
I remembered again today as one of our developers deployed Confluence why 30 day trials are so nice. Like many corporate shops we deal in purchase orders. If we had to wait to get our official license it could easily be 2 weeks before the PO clears with the vendor. In the meantime we can start out using the 30 day license and then just swap in the official license key in about two weeks with no delay.
James Shore On Private Variables and Getter/Setters
It was nice to run across this post by James Shore on the silliness of default getter/setter methods. I’ve posted on this before and Alan Holub has a fairly famous/infamous rant on why Getter and Setters Are Evil.
As just one example of this, let’s look at the simple and popular “instance variables must be private” design rule.
Now for the problem with the rule. People know about the “private variables” rule but don’t think about why. So you end up with code like this. I swear to God, I see this stuff everywhere.
public class MySillyClass { private string _myFakeEncapsulatedVariable; public string getMyFakeEncapsulatedVariable() { return _myFakeEncapsulatedVariable; } public void setMyFakeEncapsulatedVariable(string var) { _myFakeEncapsulatedVariable = var; } }
From a coupling standpoint, there’s very little difference between this code and a public variable. The code follows the letter of the rule, sure. But the programmer of this class clearly hasn’t thought things through. The “private variables” rule was a mere speedbump on the way to thoughtless design.
This part of the argument is down towards the bottom of a very large post. If you haven’t run across James Shore before his blog posts are often experiential and quite enlightening on Agile and XP techniques.
SQL On Rails
My brother pointed me at an entertaining April Fool’s satire site, SQL on Rails. Favorite line of code in the screencast was:
SELECT * FROM the_internet