The answer: if an IOException occurs, the FileReader is not closed. The calling method that catches the exception can report the exception but doesn’t have the opportunity to handle the exception.
Here’s an improved (although not perfect) version:
This is a “you can only find it through careful code review” bug.
Our C# colleagues have a language feature designed for these situations. Joshua “Effective Java” Bloch proposes such a feature for Java 7, called “Automatic Resource Management”.
Why do I mention this? In keeping up with what’s coming for Java 7, I stumbled upon this proposal. I realised that in Poker Copilot’s Java code, I frequently use the poor idiom at the top of this blog entry. But I stand in good company: According to Joshua, 2/3 of the uses of the close method in the JDK are wrong.
If you are a programmer and not yet using, abusing, and relying on Stack Overflow, you are missing out. When I ask a programming question on Stack Overflow, I normally get some helpful replies within minutes. This is almost-real-time, distributed technical support that gives the right answers.
Still, home-based work has its moments. On my first day, I shaved and ironed my clothes, thinking I should treat work seriously and look the part. That lasted a day before stubble, sneakers and tracksuit paints took over. As I write this blog, I have a scruffy look that only a mother could love.
Speaking from my own experience, I think he’s right on the money throughout.
Do you work for a big corporation? Does the corporation frustrate you with password policies that seem unnecessarily complicated? You have to change you password bi-monthly. You have to use a combination of lower case, upper case, numbers, and punctuation. You can’t reuse the last 7 passwords. And so on. It frustrates you. It frustrates me.
But then I read of a Twitter employee having her Google Apps account breached, by someone who guessed her insecure password. Confidential Twitter info gets into the hands of online tabloid journalists, hungry for a story. And then I realise the wisdom of these frustrating password policies.
Part of the joy of leaving corporate consulting and running my own one-person software firm is that I am freed of onerous bureacratic tasks. Yet sometimes those onerous tasks are necessary.
Brieuc has further refined his alternative Poker Copilot icons. I really like them. My girlfriend doesn’t. I guess it’s a question of taste. However only one of us enjoys old 1950s German “Heimat” films – and it ain’t me. So maybe I’m the one with better taste.
(And guys, let’s keep the comments family-friendly this time, shall we!)
I have a bunch of unit tests that get automatically run over Poker Copilot several times a day. In theory, these help me detect when I accidentally break some feature while changing code elsewhere in the application. In practice, the unit tests are only a first line of defense – but a helpful one.
“Code coverage” is a measure (as a percentage) of how much of my code is covered by these unit tests. OCD types like to have high code coverage. Lazy people struggle to reach a double digit percentage. I oscillate between the two camps. Consider me “lazy OCD”.
Typically to get the code coverage up, you write more tests. Over the last month I’ve been tidying things up in the code, in preparation for the coming release of version 2. Finding and deleting unused methods and classes reduced the lines of code in Poker Copilot by 13.6%.
So there it is: the easy way to improve code coverage is to delete unused code. Finding that unused code is a bit trickier – unless you have IntelliJ IDEA‘s wonderful, amazing, indispensable static analysis tools.
We can confirm with you that Poker Copilot is allowed to be used as long as it contains only hand histories from hands in which you yourself have participated.
But note:
[Customers must note] that adding other players’ hand histories … may result in permanent closure of their accounts.
So there you have it. Use Poker Copilot with Full Tilt, but don’t add other players’ hand histories.
Yesterday’s Early Access Program (EAP) release was a disaster. While fixing some bugs last week I inadvertently added some multi-threading problems. These are the one-in-73 type problems: you might use Poker Copilot 73 times and only see the problem once, because they are subtle timing problems.
On the other hand, the release was very successful because it quickly revealed these problems. I fixed them late last night, added some checks that will make it harder for such problems to happen in the future, did some smoke-tests this morning, and have now released a new EAP build (#23).
That’s crowdsourcing at work. Thank you EAP community!
Why doesn’t Poker Copilot use MySQL or (shudder) Postgres?
There’s two main reasons:
User Experience
Speed
User Experience
Consider iTunes. iTunes is, fundamentally, a database with lots of data. The data is in the form of thousands of files that encode sound frequencies. In my case, iTunes has 13 Gigabytes of music in 2517 files. Plus 920 Megabytes of podcasts. Plus 14 Gigabytes of TV shows.
iPhoto is, fundamentally, also a database. This time the data is in thousands of files encoding photos.
In neither iTunes nor iPhoto is the end user expected to first install an SQL relational database system. The database is hidden from the user and managed so that the user simply sees what’s important.
I aim for Poker Copilot to have the same seamless experience one finds in iTunes and iPhoto. The complicated database management is hidden from the user.
Speed
Using an embedded database engine – which Poker Copilot does – has the potential for greater speed than a separate database server like MySQL or PostgreSQL. To get all technical, communication between a piece of software and a database server involves (in common scenarios) creating a TCP socket connection, encoding the query in a standardised manner, sending the query over the socket, retrieving the results over the socket, decoding the results, and disconnecting. Often the overhead of connecting and communicating is the most time-consuming part of the process. (There are ways to speed things up somewhat, such as connection-pooling and client-side query caching.)
An embedded database engine, if engineered for speed, can operate faster.