Showing posts with label MAC. Show all posts
Showing posts with label MAC. Show all posts

2007-06-16

Cocoa, falling at the first hurdle?

I was REALLY looking forward to programming some apps on the Mac using Cocoa and objective-C.

I am reading "Cocoa programming for MAC OS X" by Aaron Hillegas. I had read as far as page 30 when I saw the following:

"Objective-C is a very simple language. It has no visibility specifiers: All methods are public; and all instance variables are protected. (Actually, there are instance specifiers for instance variables, but they are rarely used. The default is protected, and that works nicely.)"


WHAT?

Works nicely? I disagree! It is actually possible to make a class's method private by not including it in the interface declaration (myclass.h) and just adding the implementation file instead, but what about protected methods?

public
I expose as little as needed to ensure the class provides the service it was designed to. The signatures/names of members in my public area change as little as possible so as not to break other people's code. Public members are therefore inflexible.

protected
I am happy to expose a few more methods here. Typically virtual methods so that anyone inheriting from my class can hook in their own code and modify the behaviour of my class. Protected members are a little more flexible to change as fewer lines of code depend on them, but I still try to change them as little as possible.

internal / friend
These are vital to me. They allow me (and only me) access to certain members of other classes. I find this invaluable when I need to have some kind of collaboration between classes in a framework that nobody else should have access to, including descendants of my own classes that are not in the same assembly/module.

private
An absolute necessity. Access to some members would allow a consumer to manipulate members of your class without obeying "the rules". This would include adding items to a private array member without going through the relevant method which might perform other tasks such as


  1. Enforcing read-only.

  2. Checking security permissions.

  3. Executing other methods to enforce proper business procedure.



As you can see, I feel very strongly about encapsulation. It provides flexibility to change the way you provide your service and enforces correct behaviour. When you order new computer from a manufacturer you don't walk along the conveyor belt interfering with the way each element is added do you? You interface with the manufacturer using the approved process (public PlaceOrder) and then leave them to get on with the 100 or so private procedures they go through to fulfill the order.

Never before have I read so little about a language before deciding it is a waste of time proceeding! Maybe encapsulation will be implemented along with the new garbage collection features (I wont go into reference counting) that is coming in the next version of Mac OS X. I'll have to wait and see!

Enough rails for me

That's it, I've had enough of Ruby on Rails!

I like the rails part, it's a very clever approach, but I really dislike the Ruby part!

The final straw occurred yesterday. It's very common in OOP to have the constructor set default values for your object just in case the consumer of your class does not set them. In C# I would do something like this.....

public class Post : MyBaseClass
{
private bool isPost = true;
}

In Ruby I was trying to achieve this simple behaviour...

01: IsPost is set to true
02: A form is displayed with the default value
03: User changes the value
04: My Post instance is updated with the values from the form

I tried to override Initialize() only.

def Initialize
super
is_post = true
end

Now Post.new(params[:post]) is not reachable for some reason.


So in my Post class I did this

def Initialize(* params)
super(params)
is_post = true
end

The problem here is when I try to initialize the values from the form in my controller class.

post = Post.new(params[:post])

This means that the super(params) is called (which sets is_post to the value in the form) and then sets is_post = true. So my value is always true regardless of what the user enters.

So I tried putting "is_post = true" before the call to super, but that throws a null reference exception.

Finally someone told me to merge hashes like this

{:is_post => true}.merge(params);
super(params)

I don't recall the error, but that didn't work either.


I'm sorry, but ANY language that gives me this much hassle just to set a default is not worth it.

C# on rails, now *that* would be nice!