Re: is this badly written code?
Re: is this badly written code?
- Subject: Re: is this badly written code?
- From: Johnny Lundy <email@hidden>
- Date: Tue, 15 Apr 2008 11:44:59 -0400
My Cocoa coding is for hobby only, and only for about 4 years, so I do
not have experience with working in teams or on multi-developer
projects.
But I see this issue in other development environments of recent issue
as well. Apple has provided a rich set of finely-granulated APIs,
which allow a huge amount of flexibility and customization. The
downside of this (true with the Carbon C APIs as well) is that to do a
simple thing involves calling 3 or 4 APIs just to set the "default"
values for pieces of the final method call that you want.
Here's an example I just finished. All I want is to retrieve 14 bytes
of data from accessing a single URL. In a shell script I could do it
with one "curl" call. In Cocoa, I have to
1) Make a string into an NSURL
2) Make an NSURLRequest from the NSURL
3) Call the convenience method "[NSURLConnection
sendSynchronousRequest:..." to avoid having to even further specify
details about what I want to do.
So this comes down to
[NSURLConnection sendSynchronousRequest: [NSURLRequest requestWithURL:
[NSURL URLWithString: @"http://random.org/integers/?num=1&min=1&max=4&col=5&base=10&format=plain&rnd=new
"]] returningResponse: NULL error:NULL];
Now that is going to be a bitch to debug if I write it that way to
begin with, because there is no way to get the intermediate values
without putting expressions in the gdb console. So I have developed
the habit of doing it in the following way:
1) Write each portion of the code by assigning to intermediate ivars.
This of course is easiest if you just type them in-line as you write
them, but then of course they will not show up in the debugger so it
is better to go ahead and type them in the @interface section.
(As an aside, wouldn't it be great if Xcode had a feature to add ivar
declarations to @interface based on what you selected - e.g. select
the "NSString *foo" part of a statement "NSString *foo = [NSString
string]" statement and Xcode would automatically add "NSString *foo;"
to the @interface and remove the characters up to the "f" in "foo"
from the selected statement. I find myself doing this about 50 times a
day.)
2) Debug the code block. If it runs correctly, then I am left with
these single-use ivars which clog up my header file and make it
difficult for another person to tell which is the real result
variable. They also have to keep referring back to the intermediate
vars to see what their values are in order to interpret the main API
call. It becomes harder and harder to construct names for these ivars
as they all have very similar contents and purposes. So you wind up
with ivars named
"voterCountForVoterAfterRandomChoiceIsMadeButBeforeFinalSorting" and
so forth.
3) For each ivar that I used, I copy the right side of the assignment
statement and paste it in place of the name of the ivar in the
subsequent code lines.
4) Then after testing the new code, I delete all the ivar assignments
and delete their definitions from @interface.
N.B.: I don't do this if the intermediate variables are used more than
once in the final code call - in those cases I leave the variable name
in there to avoid calculating it more than once.
What would be great is if Apple would give us many more convenience
methods that pared it down to the most common things - like a "-
(NSStriing *) NSSynchronousURLFetch:(NSString *)theURL" method that
just takes a string which represents the URL and returns a string
which is the content at that URL.
I'd also be very interested in others' views on this.
Date: Mon, 14 Apr 2008 22:53:16 -0400
From: "Adam Gerson" <email@hidden>
Subject: is this badly written code?
To: "email@hidden" <email@hidden>
Message-ID:
<email@hidden>
Content-Type: text/plain; charset=ISO-8859-1
In cocoa its very tempting to write a single line of code like:
NSManagedObject *selectedTreeObject = [[[[[self delegate]
mainWindowController] treeController] selectedObjects]
objectAtIndex:0];
or to flush it out in to individual lines:
NSWindowController *mainWindow = [[self delegate]
mainWindowController];
NSTreeController *treeController = [mainWindow treeController];
NSArray *selectedTreeObjects = [treeController selectedObjects];
NSManagedObject *selectedTreeObject = [selectedTreeObjects
objectAtIndex:0];
I am looking for some guidance on best practices in a situation with a
lot of nested calls like this. If ultimately the only value I care
about is the final one, selectedTreeObject, whats the best way to go
about getting it? I know "best" is a subjective word. Interested to
hear all of your opinions.
Adam
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden