I’ve had a couple of bug reports about my Protocol Buffers port – both nicely detailed, and one including a patch to fix it. (It’s only due to my lack of timeliness in actually submitting the change that the second bug report occurred. Oops.)
The bug was in text formatting (although it also affected parsing). I was using the default
ToString behaviour for numbers, which meant that floats and doubles were being formatted as "50,15" in Germany instead of "50.15". The unit tests caught this, but only if you ran them on a machine with an appropriate default culture.
Aaargh. I’ve been struggling with a similar problem in a library I can’t change, which uses the system default time zone for various calculations in Java. When you’re running server code, the default time zone is almost never the one you want to use, and it certainly isn’t in my case.
A similar problem is Java’s decision to use the system default encoding in all kinds of bizarre places –
FileReader doesn’t even let you specify the encoding, which makes it almost entirely useless in my view.
So I’ve been wondering how we could fix this and problems like it. One option is to completely remove the defaults. If you always had to pass in a
Charset when you call any method which might be culturally sensitive.
Making life easier (in .NET)
It strikes me that .NET has a useful abstraction here: the assembly as the unit of deployment. (Java’s closest equivalent is probably a jar file, which probably gets messier.)
Within one assembly, I suspect in many cases you always want to make the same decision. For example, in protocol buffers I would like to use the invariant culture all the time. It would be nice if I could say that, and then get the right behaviour by default. Here are the options I’d like to be able to apply (for each of culture, time zone and character encoding – there may be others):
- Use a culture-neutral default (the invariant culture, UTF-8, UTC)
- Use a specific set of values (e.g. en-GB, Windows-1252, "Europe/London")
- Use the system default values
- Use whatever the calling assembly is using
Of course you should still have the option of specifying overrides on a per call basis, but I think this might be a way forward.
Thoughts? I realise it’s almost certainly too late for this to actually be implemented now, but would it have been a good idea? Or is it just an alternative source of confusion?