Coding with Joy
Supporting iOS 3.1.3 while using the Twitter framework

If you want to use the new Twitter framework in iOS 5 in your app, but you ALSO want to continue supporting 3.1.3 devices you have to do TWO things:

1) Weak link the Twitter.framework (as expected)

2) Weak link the system library (libSystem.dylib)

The second item may be a surpise.  This is necessary because the Twitter framework’s API uses blocks (function literals / closures) which are not available in 3.1.3.  Since these are missing, your app will crash on load if you don’t weak link the system library.

I learned this helpful info from this page on Stack Overflow.  You need to first ADD the libSystem.dylib framework and then change the linking to “Optional”.

Should instance variables always be private?

 In college I was taught “all instance variables should be private”.  While this is intentionally overstated to compensate of the lack of experience in students, I think it is potentially harmful.


Why is this practice encouraged?

  1. Encapsulation.  In many cases the data inside an object is purely for internal use and should not be exposed to users of the class AT ALL, whether by using a public variable or by using a getter and setter.  This is data that is actually conceptually private.  This is “encapsulation”, which is the cornerstone of Object Oriented Programming.
  2. Prevent Breaking API Changes.  Changing from public variable to use a getter/setter will break all of the clients of the class because the assignment syntax is no longer valid.
  3. Implementation Independence.  Using a getter and setter instead of a public variable frees the implementation to change the internal representation of the data over time while presenting the same interface (class type) to the clients of the class.
  4. Interfaces.  Using a getter and setter opens the door for abstracting out a Java Interface for the class that could be used to support several different implementations.


Do these translate to real benefits for everyday programming in the real world?

  • #1 (Encapsulation) is a very important truth to learn and practice and should be followed religiously.
  • #2 (Prevent Breaking API Changes) and #3 (Implementation Independence) are really only important to follow for people writing libraries that will be used in client code outside your control.  But for a lot of real-world programs, all client code will be available to the creator of the class, so if getters and setters need to be introduced they can be added with a programmatic refactoring executed by Eclipse or some other IDE.  This ability to automatically refactor code to introduce getters and setters is the primary contributor to making public instance variables acceptable.
  • #4 (Interfaces) is not commonly required, and if it is then getters and setters can be introduced via automatic refactoring in the same way as above.


Is there any harm in practicing “all instance variables should be private”?

Many Java programmers will generate getters and setters for EVERY instance variable in EVERY class they write.  This results in serious boilerplate and decreases code readability in two ways:

  1. A huge number of trivial methods (getters and setters) to read through when examining a source file.
  2. Setter methods are syntactically less expressive than the assignment operator.  myVariable=99 is clearer than setMyVariable(99) 


Exceptions to the Rule

I would argue that there are a number of cases where public instance variables make sense even without considering the existence of automatic refactoring tools.  For example:


1) Immutable instance “variables”.

public class LatLng {  public final double latitude;  public final double longitude;
  public LatLng(double latitude, double longitude) {    this.latitude = latitude;    this.longitude = longitude;  }}

Since the values cannot be changed, there is limited value in making them private.  However, adding accessor methods would allow you to change the internal representation of the data, which could be worthwhile depending on the likelihood of this occurring.


2) “Record” style classes that merely hold data and have no behavior.

public class StringHolder {  public String value;}

StringHolder is a class used in the Axis web services library that is really just a mutable String.  Strings are immutable in Java, so this class allows you pass around a reference to a String, primarily to serve as a “output” variable passed to a procedure.  In Pascal you would just use the “var” or “out” modifier on the variable and forego the class.

Adding getters and setters to this class would be pointless since the sole purpose for the class is to read and write the value and because the internal representation is highly unlikely to ever change.  

Some other common uses of “record” classes are 1) to return multiple values from a function, and 2) to bundle a bunch of function parameters into an object to simulate named parameters.


Scala

Some new JVM languages have features that make much of this discussion irrelevant.  Scala, for example, avoids all sorts of these problems with the following features:

  1. "Property" syntax allows you to use the assignment operator to invoke the setter method indirectly.  In Scala myVariable=99 may invoke a setter or access a value directly.  This allows getters and setters to be introduced without affecting existing client code.
  2. Immutability is encouraged as the default, and immutable values can be made public with less risk.
  3. Getters (and setters for mutable values) are automatically generated by the compiler and do not need to be coded (or read).  (This also means that it’s not really even possible to have public instance variables, merely public getters and setters.)
  4. Built-in syntax for working with Tuples (like pairs of values) can alleviate the need for creating classes to return multiple values from a function
  5. Named parameters eliminate the need for classes that exist merely to bundle up a lot of function parameters.

Conclusion

In Java saying “all instance variables should be private” is too simplistic; the decision should be made more carefully with consideration of the cost/benefits because there are real costs to readability by introducing getters and setters and often the benefit is close to zero.

How about in Scala?  In Scala, encapsulation is really the only important consideration since 1) there are no downsides to having getters and setters and 2) there is little need for public variables (and it isn’t really impossible have them anyway).

Surprises from Mac Mini Server

I just got a Mac Mini Server at work, primarily to replace my very aged, six-year-old PC.  I will also use it for mac (web) development because it is more powerful than my other mac, but running Windows on it was really the reason I got it.  Actually, my boss chose it for me.  I thought it was a good choice at first since the hardware specs on it are better than the regular client version of the mini.  But little did I know the challenges that awaited me.

Mac OS X Server doesn’t include the Bootcamp Assistant app or the boot camp Windows drivers, so getting Windows on it proved to be a bit of a challenge.  And even before that consideration—the thing doesn’t have a DVD/CD drive!

So the first step was to visit the Apple store to buy a Superdrive, a USB external optical drive.  But surprise, the actual product name is the “Macbook Air Superdrive”.  This drive says it only works with the Macbook Air and nothing else; that’s because all other Apple computers have an optical drive included… well, except the Mac Mini Server.  I couldn’t believe that this drive would only work with one particular computer, so the salesman checked in back, and yep, sure enough, it will work with the Mac Mini too.  So after paying $79.99, I was on my way.

The next step was partitioning the drive.  I first tried to copy the Bootcamp Assistant from the client version of Snow Leopard and run on the server.  No dice; the app won’t run.  Then I tried booting from the client Snow Leopard DVD to run it from there.  No dice.  Ok, that’s alright, I’ll just partition the thing myself.  So I booted from the server’s install DVD (by holding C at startup) and ran the Disk Utility.  I figured out how to resize the existing partition rather than recreating a new one and then added a partition for Windows to use.  The first time I did it I forgot that the partition must be 32GB or smaller since it is formatted with the fat32 file system.  Then I also learned that you have to let windows format the partition before the install even though you just created and formatted it with the mac.  If Windows doesn’t do the formatting, then it won’t work.  So I rebooted and held C to startup from the Windows install CD and installed Windows XP.

Now, the next step was getting the boot camp windows drivers installed for all this mac hardware.  Since the drivers aren’t on the Mac OS X Server DVD and are not available from Apple’s web site, the only legal way to get them is from a copy of the client version of Snow Leopard.  And ideally it would be from the most recent client version of the Mac Mini since some of the hardware is the same.  

I didn’t have a the DVD from the mini, but I did have a Snow Leopard client DVD, so I inserted that while booted into Windows and installed the boot camp drivers.  Then I downloaded the 2 updates to the boot camp drivers from apple’s web site (3.1 and 3.2) and installed them.  After all that, there were still a lot of missing drivers, most importantly, the video card driver.  The video performance was terrible, so that really needed a resolution.  Google helped me discover that the video card is actually an Nvidia GeForce 320M card.  I found the driver on their web site and installed it and the video was fixed.

The next driver I tackled was the ethernet driver.  This turned out to be a Broadcom NetExtreme Desktop card and I downloaded the drivers from their site.  Ethernet solved.

After all this the remaining missing drivers were for the “coprocessor” and the “SM bus controller”.  I haven’t gotten these working yet, and I’m not that motivated to spend time on it since everything I need seems to be working.

My next step will be to install Parallels on the Mac side and hook it up to my windows partition.  Then I am also planning to convert my two 500GB drives into a RAID0 setup to increase disk speed in Mac OS.  Once this is all complete I expect this to be a very performant system.  

So was it worth it?  It’s hard to say. I wish I had known the work involved before going into it, but I’m satisfied with the result now that it’s done.  I considered just replacing the server OS with the client version of Snow Leopard (so I could use Bootcamp Assistant, etc), but reading online showed me that this was just as hard (or harder) than just installing Windows the way I did it.  Hopefully this will help someone out there.