Thursday, July 24, 2008

Hillegass Ch. 3

This chapter introduces the idea of composition. OOP enthusiasts may frequently use inheritance to construct new classes. "X is a Y, so X inherits from Y." But Hillegass says it's much more common to employ the "X uses Y, so X contains a Y" approach in Objective C.

The application in this chapter imports a simple class called LotteryEntry, each instance of which has two variables that are numbers (NSNumber objects) and one date (NSCalendarDate). In the main script we'll loop once to construct some LotteryEntry instances, store them in an array, and then display the result.

Here is the code for the LotteryEntry class. It uses a function from objc ("objc.ivar()") which I don't understand, but I know it is designed to make Python instance variables play nice with bindings, as we'll see in the next post. (And no, I don't understand what the 'i' is all about yet).

from Foundation import *
import objc
import random

class LotteryEntry(NSObject):
x = objc.ivar(u'x','i')
y = objc.ivar(u'y','i')
d = objc.ivar(u"date")

def init(self):
print "init LotteryEntry"
self = super(LotteryEntry, self).init()
return self

def prepareRandomNumbers(self):
print "prepareRandomNumbers",
R = range(1,101)
self.setX_(
NSNumber.numberWithInt_(
random.choice(R)))
self.setY_(
NSNumber.numberWithInt_(
random.choice(R)))
print self.x, self.y

def description(self):
sec = self.date.secondOfMinute()
s = NSString.alloc().initWithFormat_(
"%s: %d and %d" % (
sec,
self.x,
self.y))
return s

def setX_(self,n): self.x = n
def setY_(self,n): self.y = n
def setDate(self):
self.date = NSCalendarDate.calendarDate()

Here is the main script.

from Foundation import *
import LotteryEntry
import time

def report_(array):
for i in range(array.count()):
L = array.objectAtIndex_(i)
print L.description()

def main():
array = NSMutableArray.alloc().init()
for i in range(3):
L = LotteryEntry.LotteryEntry.alloc().init()
L.prepareRandomNumbers()
L.setDate()
array.addObject_(L)
time.sleep(1.0) # to make dates interesting
report_(array)

main()

This app does not have a GUI. We run it in the usual way from Terminal, and this is what it prints:

init LotteryEntry
prepareRandomNumbers 38 52
init LotteryEntry
prepareRandomNumbers 78 25
init LotteryEntry
prepareRandomNumbers 47 82
4: 38 and 52
5: 78 and 25
6: 47 and 82