So I finally bought eatnumber1.com... i've been looking at it since I was like 14.
Many people have asked me "why eatnumber1... what does it mean". The answer is *drum roll* nothing! Eatnumber1 is a name I came up with when I was signing up for AOL when I was like 8 years old, and couldn't think of anything else that wasn't taken. The really good thing about it, and the biggest reason I keep using it is because nobody... absolutely nobody... uses it but me, so I can always know that if I go to a site, I can sign up on the site using eatnumber1.
So now that I have eatnumber1.com, I've setup a few things... Google's management of a few of the subdomains (mail.eatnumber1.com, calendar.eatnumber1.com, blog.eatnumber1.com, etc...), and I pointed a few other subdomains at my various computers. My only complaints are that Google's domain services don't have things like Gmail labs, or any of the latest Gmail features in fact. To get around this, I forwarded all the mail to russ@eatnumber1.com (my new primary email address) to eatnumber1@gmail.com (my old primary), registered russ@eatnumber1.com with gmail, and set it as my primary. So now, I login to eatnumber1@gmail.com, but can treat it as if it was russ@eatnumber1.com. My other complaint is with dns hosting. I wanted to get a host with dynamic dns support so I could give my systems with dynamic ips (laptop) a subdomain, but Godaddy (my registrar) doesn't support it. The only dns host I could find that would host a tier 1 domain that supported dynamic dns for free was dnsexit, and they required that you put a link to them on your website... since i'm not pointing eatnumber1.com at anything, there is no website to put a link to. Also, I later found out that they don't support SRV records which I need to play with google's custom domain google chat services. So now, i'm just using Godaddy for dns (I actually like their custom DNS interface), and the only complaint I have with them is that they don't support dynamic DNS.
Tuesday, November 25, 2008
Tuesday, September 30, 2008
Finally fixing the Cloneable problem
So I finally had a use for Java's Cloneable interface. I needed to make a rather large object hierarchy cloneable. In java, to make an object cloneable (using the cloneable interface), you need to make it (or one of it's superclasses) implement cloneable, then you usually override Object's clone method with a public variant of it. That's not all however. If your object has instance variables which are non-primitive, and mutable (I.E. not String, Integer, Short, Long, etc... all the immutable types), your clone method has to handle cloning those objects itself.
Now this is all well and good, but there's one big problem with it... there is no guarantee that a subclass who needs to implement clone in order to correctly copy it's reference fields, actually does it. Even worse, if a class doesn't implement it, and you call cone on it, it will work, and just give you an incomplete copy of the object.
Since Java 5, they have added support for processing annotations at compile time, so I figured "why not a @IsCloneable annotation?".
Here's the jar. (Edit: 2010-10-12 The jar has been lost.)
So you have the code, now all you have to do is put that in your classpath and use apt instead of javac to compile your code. apt is a program included since Java 5 which accepts all the same options as javac, so it can be a simple drop-in replacement.
To use it in the code itself, you just need to annotate the head of the object hirearchy with @IsCloneable.
It also supports a few more advanced usages. If, for example, you have a class that you do not want to support cloning, just annotate the class with @NotCloneable and my code will stop enforcing policy right there.
Also, if you have a mutable reference field that (for whatever reason) you want to be shallow copied, just annotate that field with @SkipClone
P.S. At the moment, it is java 5 only. Java 6 support is coming.
P.P.S. It is GPL licensed code (source is in the jar), but I may relicense it if someone asks really nicely.
P.P.P.S. The current implementation has one limitation... you have to compile the entire object hierarchy at once. The only workaround for it is to annotate every class you compile separately with @IsCloneable
Now this is all well and good, but there's one big problem with it... there is no guarantee that a subclass who needs to implement clone in order to correctly copy it's reference fields, actually does it. Even worse, if a class doesn't implement it, and you call cone on it, it will work, and just give you an incomplete copy of the object.
Since Java 5, they have added support for processing annotations at compile time, so I figured "why not a @IsCloneable annotation?".
Here's the jar. (Edit: 2010-10-12 The jar has been lost.)
So you have the code, now all you have to do is put that in your classpath and use apt instead of javac to compile your code. apt is a program included since Java 5 which accepts all the same options as javac, so it can be a simple drop-in replacement.
To use it in the code itself, you just need to annotate the head of the object hirearchy with @IsCloneable.
It also supports a few more advanced usages. If, for example, you have a class that you do not want to support cloning, just annotate the class with @NotCloneable and my code will stop enforcing policy right there.
Also, if you have a mutable reference field that (for whatever reason) you want to be shallow copied, just annotate that field with @SkipClone
P.S. At the moment, it is java 5 only. Java 6 support is coming.
P.P.S. It is GPL licensed code (source is in the jar), but I may relicense it if someone asks really nicely.
P.P.P.S. The current implementation has one limitation... you have to compile the entire object hierarchy at once. The only workaround for it is to annotate every class you compile separately with @IsCloneable
Thursday, August 14, 2008
Negative indexed arrays.
In first describing how rediculous C and C++ was to my class when I was in my first C++ programming course, I remember him saying that you can even create negative indexed arrays. Now that I am a bit wiser in the ways of C++ and memory management, I actually know how to do it!
The following small C++ program illustrates:
So if the array looks like this:
Therefore if you add one to that, your array's element 0 would point at memory address 0xFADD, and it's element -1 would point at memory address 0xFADC.
REMEMBER: Don't try to delete an array like this before restoring it to the way it originally was or you will get a segfault ^_^.
A shorter way of doing it that doesn't involve using new is:
The following small C++ program illustrates:
When executed, it gives us this:#include <iostream> using namespace std; int main() { const char** array = new const char*[2]; array[0] = "Hello"; array[1] = "World!"; cout << (++array)[-1] << endl; delete --array; }
The reason this happens is that since arrays in C and C++ are linear in memory, you can do math on them (the ++array and --array).$ g++ -Wall NegArray.cpp -o NegArray && ./NegArray Hello
So if the array looks like this:
If you printed your array (without an index), you would see 0xFADC... the address of the first element.0xFADC 0xFADD <-- This is the address ----------------- | Hello | World | -----------------
Therefore if you add one to that, your array's element 0 would point at memory address 0xFADD, and it's element -1 would point at memory address 0xFADC.
REMEMBER: Don't try to delete an array like this before restoring it to the way it originally was or you will get a segfault ^_^.
A shorter way of doing it that doesn't involve using new is:
#include <iostream> #include <string> using namespace std; int main() { const string array[2] = { "Hello", "World!" }; cout << ((const string*) &array + 1)[-1] << endl; }
Subscribe to:
Posts (Atom)