| Software will save us |
Unqualified ramblings about technology and the sorry state of software development.
- Recent
- Popular
- Tags (0)
- Subscribers (2)
- Setter methods make kittens cryJune 22
-
Do use setters if being edited is the central purpose of that class. Do not use setter methods to create an object. Setter methods intended for creation will still be accessible during the whole lifetime of the object. Someone might use them and break all your stuff. Basically everything involving caches or hashCode() will die in your arms. Like when changing an attribute will cause some remote piece of code have maps with broken mappings and suddenly sport sets with duplicate elements. Being paranoid makes for good code karma.
Furthermore, do not use setters to wire up required attributes. I often see code like this:
Foo foo = new Foo(); foo.setAttribute1(a1); foo.setAttribute2(a2); foo.setAttribute3(a3);This is bad because until the last line has executed, foo lives in some sort of twilight zone, where it exists but may not be used yet. Your class should not allow to create an object with invalid state. Better use the constructor to wire up attributes:
Foo foo = new Foo(a1, a2, a3);Some people will argue that this will become hard to read if you have a lot of attributes. In such cases you should use a Builder separate factory class that collects all attributes with setters and can create the object once all required attributes are present (otherwise throw an exception). This shifts the enforcement of valid object creation from compile time to runtime, b
- You don't know Java: Method type parametersApril 12
-
When someone tells you they know Java, smile and say "no, you don't". Proceed to soften them up with questions about covariance and contravariance and how they relate to parametrized types. When they start crying, go in for the kill.
But let's talk about something nice today: Method type parameters. Few people know that type parameters in Java are not limited to types, but that every method and constructor can declare their own type parameters. And if this alone wasn't cool enough, it can actually be useful!
To illustrate, I need a couple of interfaces from Java kindergarden:
interface CanWalk { void walk(int steps); } interface CanSwim { void swim(int strokes); } interface CanSleep { void sleep(int minutes); boolean isSleeping(); } interface Animal implements CanSleep { } interface Cat implements Animal, CanWalk { } interface Dog implements Animal, CanWalk, CanSwim { }Say we want to write a method that simply takes an Animal and returns it. This is the way we used to roll:
Animal returnMe(Animal animal) { return animal; }What's bad about this method is, that it returns its value as Animal, even if we gave it a Cat. So if we wanted our cat back, we need to cast it manually:
Cat cat = (Cat)returnMe(new Cat());We can improve on this by binding a type variable to the returnMe method
- Names are importantMarch 21 2007
-
For a profession that is all about naming things, most programmers are being terribly careless with names. Although you get away with it most of the time, you look so immensely stupid when two pieces of code disagree over the meaning of a name. Names are important.
One of the things I still love about Perl is that, by convention, it is considered rude to invade other people's namespace. So we put all our public methods and constants into the @EXPORT_OK array and let the client decide which part of that he wants to use in their code. I should be able to do the same with code extending existing classes: Let me decide which extensions I want patched in on a per-class basis. I believe extension methods in C# 3.0 work this way. Do copy this.
Another name issue few languages get right are namespaces. Namespaces are important, because sooner or later you will have two different Node classes in your project and you need to tell your code which one to use. Let's look how some popular languages are dealing with this:
PHPBashing PHP is a bit like beating up an old man, but here we go anyway: PHP has no notion of namespaces at all. To work around this, people are using Really_Long_Classnames_With_Packagish_Names_Prefixed to lessen the chance of namespace
- Whoops! Open classes not cool after all!March 20 2007
-
Ruby, Perl and many other languages let you reopen an existing class or namespace and add additional methods to it, or replace existing methods with new code. Everyone thinks that is "like super-cool" and "really feels the spirit of getting things done", probably accompanied by some generic "LOL Java, agile languages FTW!" rant.
Surprisingly, open classes have one serious problem: People are using them!
Right now the two most popular uses for reopening classes are (1) adding methods to core classes like objects or lists and (2) patching totally not public code with your own funky version. Both are terrifyingly bad ideas which will probably break with the next update of the code you're patching, or as soon as another clever library attempts to do the same. But let's enjoy some examples together:
It is impossible to use prototype.js and json.js at the same time because prototype.js does something nasty to Object.prototype. But never mind since these are only the two most commonly Javascript libraries on the planet.
What Rails is doing to the Ruby core, and what some plugins are doing to Rails, is downright scary in some places. Thankfully Rails is heavily maintained and bugs are patched quickly.
While developing a
- Gapless MP3 loops in FlashJanuary 16 2007
-
When encoding a sound loop as MP3, the encoder will add ugly gaps of silence at the beginning and end of your track, making the resulting file not very loopable at all. This is due to the way MP3 encoding works.
Although there are some instructions (scroll down to "Part 2") how to remove those gaps from your sound file, the amount of hackery involved is not for the faint of heart. The same guy also wrote a tool to automate the process but it's restricted to a maximum of 8 seconds of sound, and you can totally not buy a full version.
You're lucky if you're working in Flash however. The MP3 encoder inside the Flash IDE knows about the problem and will make sure any MP3 it compresses will loop without gaps. So:
- Have an uncompressed sound loop as WAV oder AIFF. If your loop is already an MP3, remove the silent padding at the beginning and end of the track and save it as WAV.
- Import the uncompressed sound into the library of your clip.
- In the sound properties, set the desired MP3 compression.
- Loop away.
