Re: Preferred language on MacOSX
On Apr 23, 2011, at 1:00 PM, Erik Ronström wrote:
> The main problem for me is that I'm quite new to both LW (and Lisp in general) and Cocoa, so even when I do find the right objective c classes in the Cocoa documentation, I have a hard time figuring out how to call it the right way from LW. But now that I begun to collect some examples, things will get easier.
Yes, everybody goes through this learning phase, I remember it well - in fact, for many things, I'm still learning!
Whenever possible, try to use the example code of others, especially the example code from Apple's documentation.
To take your question as an example:
1. Search google for "cocoa preferred locale language site:developer.apple.com"
(note the restriction in the search to apple's developer site.)
2. The first hit is:
<http://developer.apple.com/library/ios/#documentation/MacOSX/Conceptual/BPInternational/Articles/ChoosingLocalizations.html>
at the bottom of this page is the following example code which the docs describe thus:
"The following example shows you to get the list of preferred languages from the defaults database using Cocoa. The returned array contains the languages associated with the AppleLanguages key in the user's preferred order. Thus, in most cases, you would simply want to get the first object in the array."
and the code:
NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:@"AppleLanguages"];
NSString* preferredLang = [languages objectAtIndex:0];
3. Note that this objective-c code uses three temporary variables which are completely unnecessary. IOW, the code could be written as:
[[[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"] objectAtIndex:0]
which is much lispier, since each objective-c call returns a value, usually an NSObject of some sort, just as each lisp form returns a value, and these can just be chained - no need for intermediate variables.
Translating objective-c calls is usually a matter of converting each left square brace [ into a call of the form:
(objc:invoke
or, if you want to return a specific type of lisp object rather than the normal objective-c return value which is usually some sort of NSObject or a raw C value, use:
(objc:invoke-into
In the case of our example, the final call (i.e., for the call to objectAtIndex:) which messages an NSArray and asks for the object at a particular index, returns an NSString, since the objectForKey:@"AppleLanguages" is an NSArray of NSStrings. So we want to use:
(objc:invoke-into 'string
To make all of this easier for myself, I use the following macros:
(defmacro @ (&body body) `(objc:invoke ,@body))
(defmacro @into (&body body) `(objc:invoke-into ,@body))
Using these, the default-language function would look like this:
(defun default-language ()
(@into 'string
(@ (@ "NSUserDefaults" "standardUserDefaults") "objectForKey:" "AppleLanguages")
"objectAtIndex:" 0))
which is a bit easier to type.
>
> Thanks again!
You're very welcome, and best of luck with LispWorks and Cocoa!
warmest regards,
Ralph
Raffael Cavallaro
raffaelcavallaro@me.com