Version 16 (modified by mikel, 7 years ago) (diff)


Writing the Lisp Code



First Things First


(in-package "CCL")


Defining the Converter Class


(defclass converter (ns:ns-object)
  (:metaclass ns:+ns-object))



(:metaclass ns:+ns-object)


Next, we define the method "convertCurrency:atRate:":

(objc:defmethod (#/convertCurrency:atRate: :float) 
  (* currency rate))




The number of arguments to an Objective-C method is the number of colons in the name, plus one. Each colon indicates an argument, and there is always an extra "self" argument that refers to the object that receives the message. The "self" argument is implicit in Objective-C definitions, but it's just another argument in the Lisp code.

We indicate the return type and the types of arguments in the method definition by surrounding parameters and the method name with parentheses, and appending the type name. Thus, for example,

(#/convertCurrency:atRate: :float)

means that the return type of the method is :FLOAT, and

(self converter)

means that the type of the object that receives the convertCurrency:atRate: message is Converter.

You'll see these same conventions repeated in the next section.

Defining the ConverterController Class

The previous section defined the Model class, Converter. All we need now is a definition for the ConverterController class. Recall from your reading of Apple's Tutorial that the CurrencyConverter example uses the Model-View-Controller paradigm. You used InterfaceBuilder to construct the application's views. The Converter class provides the model that represents application data. Now we define the controller class, ConverterController, which connects the View and the Model.

Here's the Lisp definition of the ConverterController? class:

(defclass converter-controller (ns:ns-object)
  ((amount-field :foreign-type :id :accessor amount-field)
   (converter :foreign-type :id :accessor converter)
   (dollar-field :foreign-type :id :accessor dollar-field)
   (rate-field :foreign-type :id :accessor rate-field))
  (:metaclass ns:+ns-object))

Once again we use the Objective-C bridge to define an Objective-C class. This time, we provide several instance-variable definitions in the class. We also explicitly define the names of accessor functions for each of them. The :FOREIGN-TYPE initargs enable us to specify the types of the fields in the foreign (Objective-C) class.

Each field in the definition of the ConverterController class is an outlet that will be used to store a reference to one of the UI fields that you created in InterfaceBuilder. For example, amount-field will be connected to the "Amount" text field.

Why did we spell the name "amount-field" in Lisp code, and "amountField" when creating the outlet in InterfaceBuilder? The Objective-C bridge automatically converts Lisp-style field names (like "amount-field") to Objective C-style field names (like "amountField"), when handling class definitions.

The converter field at launch time contains a reference to the Converter object, whose class definition is in the previous section.

The final piece of the implementation is a definition of the "convert:" method. This is the method that is called when a user clicks the "Convert" button in the user interface.

(objc:defmethod #/convert: ((self converter-controller) sender)
  (let* ((conv (converter self))
         (dollar-field (dollar-field self))
         (rate-field (rate-field self))
         (amount-field (amount-field self))
         (dollars (#/floatValue dollar-field))
         (rate (#/floatValue rate-field))
         (amount (#/convertCurrency:atRate: conv dollars rate)))
    (#/setFloatValue: amount-field amount)
    (#/selectText: rate-field self)))

Just as in the Apple example, this method reads the dollar and rate values, and passes them to the "convertCurrency:atRate:" method of the Converter class. It then sets the text of the amount-field to reflect the result of the conversion. The only significant difference between this implementation and Apple's is that the code is written in Lisp rather than Objective-C.

This completes the definition of the Currency Converter's behavior. All that remains is to actually build the Cocoa application. The next section shows how to do that.

Start Previous