By Developers, For Developers

Historical errata for Programming Cocoa with Ruby

PDF PgPaper PgTypeDescriptionFixed onComments
11ERROR

Cocoa is referred to as a library - the terms “Cocoa library” and “Cocoa libraries” are used. Cocoa is not a library, it’s a framework. There’s a subtle but important distinction between the two: A framework dictates an architecture that you follow, a library is a collection of code that you can call under your own control. (These are essentially the definitions used in the Cocoa documentation.)

2008-07-15
24TYPO

Objective-C code example uses “” strings, not "" strings. It should use “” strings.

2008-07-15
20TYPO

bullet 3 - suggests “misspell ‘object’” - but ‘object’ isn’t mentioned in the code sample.

2008-07-15
25TYPO

bullet 1 - “make_menu” - what is this?

2008-07-15
54TYPO

Repeated word you you in second to last line

2008-07-15
62SUGGEST

When discussing sender.rb vs receiver.rb it might be a good opportunity to discuss why one uses NSApplication.sharedApplication and the other does, etc.

2008-07-15
64ERROR

File sandbox/sandbox.rb needs two additions:

line 15 add:
require ‘rbconfig’

line 31-33 (the ENV[‘RUBYLIB’] each block):
add after the final ‘end’
if ENV[‘RUBYLIB’]

So that the block looks like:

<code>
    ENV['RUBYLIB'].split(':').each do | path |
      $:.delete(path)
    end if ENV['RUBYLIB']
</code>

My environment doesn’t specify RUBYLIB so this block failed on the split(‘:’)

2008-07-15
66ERROR

The Controller.rb code snippet includes the choice attribute, but no mention of it is made anywhere and its not connected to the UI. In awakeFromNib, choice.stringValue= fails as @choice is nil.

2008-07-20
69TYPO

Bullet 1: “should should”

2008-07-20
70TYPO

Bullet 2 “You can give the popup a title” - you haven’t called it a “popup” before. Perhaps “combo box” instead.

2008-07-20
75SUGGEST

In bullet 2, you mention deleting Controller from IB, but don’t mention what changes or scope of changes to make to the Controller.rb class, since its the superclass for 3 other classes.

2008-07-15
76SUGGEST

Re: 4. Write enough code to see the app doing something. I suggest implementing the actions with nothing but an “I got here” string.

Um, I think you’ve refactored the original Controller class enough to show the end result of this “write enough code”. And the “better” example code is sooo much different that I have no idea what I should do to complete this exercise. The “better” code is obviously a solution for this entire chapter or equivalent. I can’t read this code and pretend to understand how I should solve bullet 4.

Which controller do I set the MainMenu’s delegate to?

That is, how do I refactor my original one Controller class into the 3 AbcController subclasses and get the app working like it did before?

2008-07-15
79SUGGEST

Sorry to harp on this one more time, but I need express my disappointment that at this stage of the book I cannot continue reading it. “better” needs to be broken into more stages of development so that I can look at the code examples to help understand what you’re talking about in the text.

On 5.6 it asks us to “spread the behaviour into the various classes”, then there should be a sample in the code tar ball showing what this looks like. The massive refactoring of “better” isn’t helpful for learning.

Sorry for ranting, but I was enjoying learning rubycocoa today and its disappointing to have to stop because I don’t have any working code to follow the tutorials with.

If any of my concerns don’t make enough sense, please email me for clarification @ drnicwilliams@gmail.com so I can help you help me :)

2008-07-15
80TYPO

Last paragraph: “Note::AppChosen is the notification name (”AppChosen" )"

In better/Constants.rb the value of Note::AppChosen is “appChosen” not “AppChosen”

2008-07-20
81SUGGEST

Perhaps explicitly reinclude Figure 5.2, but add the Note::AppChosen, etc on the Event header row to show that each column matches to one of the three Note::XXX event names.

Also, include the Constants.rb code inline instead of just mentioning that it exists.

I’m not sure that people should have to download the code tarball and have it open all the time in order to understand what you are talking about.

2008-07-20
81SUGGEST

Perhaps in WindowController.rb add an explicit “I don’t care about the ”A translated notification is available" event in the code.

Actually, does this event type equate to the Note::LogThis constant? Perhaps the labeling of one or the other be changed so they are more similar.

But perhaps add either a comment or some “do nothing” code in WindowController.rb

when_anyone_posts Note::LogThis do | notification |
# do nothing
end

just to help the reader understand what’s going on in completion across the whole app.

2008-07-20
81TYPO

Discussion of (2) (half way down page) it says:

“Previously, you had to fetch userData from a notification like this: @window.title = notification.userData[:app_name]”

I searched the PDF file and there is no mention of “notification.userData[:app_name]” anywhere in the document except on p81

2008-07-20
83SUGGEST

I’m really starting to wish this book would separate out the “learning Cocoa” and “refactoring nasty Cocoa method calls that you’ve only just learnt”.

Why not just put the explicit, unrefactored code in the Controllers and let us see what that looks like?

Then, later on, there can be a chapter on “how I like to refactor my RubyCocoa apps” to show how it can be nicer.

Also, I think you’ve changed so much code that you’re now scared to put it in the book. If you only make small changes to the code then you can put it in the book. Then reader’s can figure out what is going on.

2008-07-15
84SUGGEST

Amongst all the cartoons, it might be helpful to show a UI picture of what Fenestra will look like when it draws different app notifications.

2008-07-20
88ERROR

Getting the tests to run

In the 2nd last paragraph you mention “Fortunately, my unit tests for this class” which made me go hunting for them. I’m very glad your code includes tests as it gives examples of how to TDD this stuff which makes me happy.

To get the tests running, I had to make the following changes:

a) add “require ‘test/unit’” to the top of test/testutil.rb" else you get “uninitialized constant Test (NameError)” error

This gives us new errors relating to flexmock

b) add “require ‘flexmock/test_unit’” into test/testutil.rb - this is what you did in key-value/testutil.rb

Now we’re down to one error:

1) Error:
test_app_should_close_when_window_closes(WindowControllerTests):
OSX::OCMessageSendException: Can’t get Objective-C method signature for selector ‘is:delegated:’ of receiver #

Thoughts?

2008-07-20
88SUGGEST

An entire chapter on testing RubyCocoa apps seems in order, having read through the better/test code. Lots of yummy things to discuss; or perhaps yummy things to refactor into a rubycocoa testing library.

Or does your testing code come from a 3rd party blog post or library/gem?

2008-07-20
54TYPO

Double word “you you set ”, last paragraph

2008-07-15
73TYPO

Diagram refers to TranslatorEnlister, but the text refers it as TranslatorSupplier

2008-07-15
13SUGGEST

You say “So if you install RubyCocoa and Leopard, prepare to spend time figuring out how a picture in the text maps into an old tool.” Why would the reader have to figure out how to map to an old tool if he is running RubyCocoa and Leopard. The reader might be at the same versions of RubyCocoa and Leopard as the author. Shouldn’t the quoted line say “If you’re running at versions earlier than …”?

2008-07-15
17SUGGEST

“The ”NS" prefix is used by not only NSApplication," would read better as “The ”NS" prefix is not only used by NSApplication,"

2008-07-15
28ERROR

The Statusbarapp.app binary included with code.zip (as of 6/12/08) does not run under 10.5.2. Console.app reports the following error:

6/12/08 2:10:05 PM Statusbar[30844] * _NSAutoreleaseNoPool(): Object 0x29a020 of class NSMethodSignature autoreleased with no pool in place - just leaking
Stack: (0x91a8f12f 0x9199bec2 0x93fa560d 0x6d9f9 0x6e45f 0xe8057 0xf118c 0xf1d6a 0xef0da 0xef9f5 0xf195f 0xf1d6a 0xf8d91 0xf1ca4 0xef0da 0xfe06e 0xfe09f 0xfe0cb 0x72012)
6/12/08 2:10:05 PM [0x0-0x995995].com.exampler.StatusbarApp[30844] /Users/xxx/Desktop/code/statusbar/Statusbar.app/Contents/Resources/rb_main.rb:54: uninitialized constant NSApp (NameError)
6/12/08 2:10:05 PM com.apple.launchd[78] ([0x0-0x995995].com.exampler.StatusbarApp[30844]) Exited with exit code: 1

2008-07-20
13SUGGEST

Please, please, PLEASE specify the exact versions of Xcode and Interface Builder that you are using in the book! The current, vague reference to needing Leopard will be even more confusing down the road, when Apple will have released new versions that are likely to have new and bizarre user interface changes. You’ll recall that IB 3.0 broke all prior XCode tutorials in one fell swoop, and a lot of those tutorials didn’t specify which version they were written for.

2008-07-15
18TYPO

Sentence is missing a space between Include and OSX

“I’ll usually just includeOSX
and forget about it.”

2008-07-15
47SUGGEST

The explanation of a C-Stuct in Ruby is confusing and the introduction comes out of nowhere imho.

While I get it after reading the passage a many times, and seeing the illustration… it still makes limited sense.

I’d suggest re-writing this from a ruby point of view, since Ruby doesn’t have stucts.

starting with:

“There’s something odd about NSRange. Its name suggests that it’s
a descendent of NSObject, but it’s created with Ruby’s new, not
alloc.init. What gives?”

and continues on for the next few paragraphs.

2008-07-20
49SUGGEST

Nit-picky…but on a Mac, Command and option are listed before the other modifiers. So Shift-Command-R would actually be Command-Shift-R.

2008-07-20
24TYPO

In the last sentence of the second paragraph after the add_menu_to method code, Objective-C is not hyphenated.

2008-07-15
24TYPO

The Objective-C example uses “speak:” as the action. But in the ruby example, the action is “speak”, without the colon. However, for the ‘Quit’ menu item, “terminate:” does have a colon. I tried the Speak menu item with and without the colon, and both work, but the point is that the Ruby example is neither self-consistent nor is it consistent with the Objective-C snippet. And what is the point of the @#$% colon anyway? :-)

2008-07-20
25SUGGEST

Last sentence, first paragraph: “…leave off the last colon…” is misleading. You are really leaving off the last underscore, or ignoring the last colon. But you aren’t really leaving off a colon.

2008-07-20
44SUGGEST

I do not know if it would be appropriate for this book, but I’m brand new to Xcode, and one of the minor annoyances I had to track down was how to set the “hidden” expert preferences that set the username and organization name expansions used in the new file templates for things such as the copyright info. a section in the begining, describing the version and requirements related to xcode might include a blurb about this? Finding this in the Xcode documentation was a bear and not straight forward at all.

write com.apple.Xcode PBXCustomTemplateMacroDefinitions ‘{FULLUSERNAME = “My Name”;ORGANIZATIONNAME = “My Company Name”;}’

this sets the comments in a new file to be:

#

  1. Controller.rb
  2. Fenestra
    #
  3. Created by My Name on 7/7/08.
  4. Copyright © 2008 My Company Name. All rights reserved.
    #

Seeing the defaults in the headers created by a new installation of Xcode and comparing with the examples in the book made the obvious need of setting some sort of preference most irritating. Hopefully a slight blurb in the begining could eliminate this frustration for other new Xcode users. Setting these hidden preferences before executing Xcode for the first time would be very helpful.

2008-07-20
24TYPO

Methode name addItemWithTitle_action_keyEquivalent is seperated with a “-” because of newline.

IHMO Methode names should stay together.

2008-07-15
26ERROR

This I didn’t found a way to download code.zip yet, I downloaded the files mentioned on page 26 and 27 via wget.

The Statusbar.app won’t start with the error.
"
LSOpenFromURLSpec() failed with error –10810 for the file /Users/mw/work/cocoa/Statusbar.app.
"
When I build the app myself, with xCode everything works fine.

2008-07-20
27TYPO

The File in dir MacOS is named “Statusbar” and not “statusbar”.

2008-07-20
26SUGGEST

I now downloaded code.tgz. Interessting is both versions are equal. But it wouldn’t work. After a minut it is working now. I don’t have any Idea whats wrong.

Maybe this is an interessting behavior. If not just remove my post about this error, please.

log
——-
$ diff -r cocoa/Statusbar.app code/statusbar/Statusbar.app
$ open cocoa/Statusbar.app
LSOpenFromURLSpec() failed with error –10810 for the file /Users/mw/work/cocoa/Statusbar.app.
$ mkdir cocoa/statusbar
$ mv cocoa/Statusbar.app cocoa/statusbar
$ open cocoa/statusbar/Statusbar.app LSOpenFromURLSpec() failed with error –10810 for the file /Users/mw/work/cocoa/statusbar/Statusbar.app.
$ open code/statusbar/Statusbar.app
*Statusbar.app is still runing
$ open cocoa/statusbar/Statusbar.app

* quit Statusbar.app
$ open cocoa/statusbar/Statusbar.app

* Now works

2008-07-20
62TYPO

Last sentence “So, since I own exampler.” is disrupted with the figure 4.2. Or with other Words: The sentence should end on page 62 and not 63. Dunno if this is a layout thing or not. If so just tell me.

2008-07-15
17TYPO

“…is the class correspoding to …” should be “… corresponding …”

2008-07-15
52ERROR

The most recent version of Interface Builder (3.1) does not have a “File->Synchronize with Xcode”.

2008-07-20
38TYPO

Take full-screen screen shots with the translucent menu bar turned off. That way you won’t get “gunk” in the bar as in the screen shot on this page.

2009-01-08
79OK

You should make your WindowController a subclass of NSWindowController and make your LogController and AppChoiceController subclasses of NSViewController. These are important classes to understand in Cocoa and important design patterns to follow in Cocoa development, so it’d be good to teach readers the right way to do this from the start.

2009-01-08
27SUGGEST

In lines 8-9, you’re writing: “For whatever reason, the character and
modifier key strokes are set in separate methods.” Well, I think the reason is very obvious: keyEquivalent (an NSString) and keyEquivalentModifierMask (an NSUInteger bitfield) are two different instance variables of NSMenuItem that are accessed with two different accessor methods.

2008-09-02
35SUGGEST

Concerning your note “Missing:Reviewers: (…)”: Yes, I like the marginal notes style for naming your illustrations. Maybe the font size might a little bit bigger!?

2009-01-08
49TYPO

after Fig. 4.2, instead of: “after all outlets are guaranteed connected”
shouldn’t it read: “… are guaranteed to be connected”!?

2008-09-02
57TYPO

instead of “Here’s what the Apple Human Interface Guidelines writes”, the verb should be “write” according to the plural form of “guidelines”.

2008-09-02
61SUGGEST

When writing your marginal note “Missing:Reviewers: is this too much on this topic?” - you probably felt yourself that the answer should be YES. In my opinion, the 3 paragraphs from this marginal not to the headline “Try this yourself” are rather incomprehensible and superfluous here.

2008-09-02
61TYPO

In “I think that NSApplication’sterminate method”, a space before “terminate” is missing.

2008-09-02
62TYPO

instead of: “send a particular named notification”, this should read: “… particularly …” (imho)

2008-09-02
62-63SUGGEST

What’s the point of this NSDictionary vs. Ruby hash stuff under the headline “The finer points of notifications” just because “Each notification can pass along an NSDictionary”? This text passage appears rather unstructured to me, sorry.

2008-10-20
64SUGGEST

“To use them, open two shells, each of them within that directory.” - WHAT does this sentence mean??? - Do you (maybe?) mean to say “… open two terminal windows, both of them set to the notifications directory as their pwd”? Do you expect your readers to be Unix experts? In general, this whole passage about the “finer points of notifications” is jammed together rather poorly and annoyingly.

2008-09-02
67ERROR

When calling

$ cd code/counting-webapp/
$ ruby start.rb

I get the following error messages:

../sandbox.rb:29:in `install_pristine_load_path’: uninitialized constant Sandbox::RbConfig (NameError)
\tfrom ../sandbox.rb:29:in `delete_if’
\tfrom ../sandbox.rb:29:in `install_pristine_load_path’
\tfrom ../sandbox.rb:36:in `adjust_load_path’
\tfrom ../sandbox.rb:55
\tfrom start.rb:9:in `require’
\tfrom start.rb:9

2008-09-02
77TYPO

“Typing in the text field will autocompletes any matching combo-box list items.” -> “will autocomplete”

2008-09-02
81TYPO

“I can use a 2x2 table like Figure 7.2 to keep myself straight”

I’m not sure what you meant, but that table seems more like 4x5 to me…

2008-09-02
88TYPO

“to to making” -> “to making”

2008-09-02
62SUGGEST

You say “A nil argument asks to hear about notifications with any name. Try that, …”

I would suggest to add a note to remember the user to comment the line “NSApp.terminate(self)” in windowWillClose or Fenestra will always be closed on startup as soon as the first notification is sent.

2008-09-02
67ERROR

As reported by Harry G., I get the `install_pristine_load_path’ error message running $ ruby start.rb.

After I forced Ruby to load RbConfig with

require ‘rbconfig’

on the top of start.rb, the script returned an other error.

weppos:counting-webapp weppos$ ruby start.rb
../sandbox.rb:32:in `install_pristine_load_path’: private method `split’ called for nil:NilClass (NoMethodError)
from ../sandbox.rb:38:in `adjust_load_path’
from ../sandbox.rb:57
from start.rb:9:in `require’
from start.rb:9

ENV[‘RUBYLIB’] is empty and the script calls split on a nil instance.

I changed self.install_pristine_load_path to be called only when pre-requirements above are honored and I finally got the application running.

2008-09-02
55TYPO

Regarding footnote 7, IB automagically refreshes when it gets focus.

2008-09-02
12TYPO

On line 6, you have two words that are merged to one: frameworkbecause.

2008-10-20
13ERROR

Your example shows ‘false’ when requiring the library ‘osx/cocoa’. Here’s what I get

berry ~ $ irb
>> require ‘osx/cocoa’
=> true # NOTICE THIS IS TRUE AND NOT FALSE
>> OSX::RUBYCOCOA_VERSION
=> “0.13.1”
>>

2008-10-20
20TYPO

You have the sentence “I’ll usually just includeOSX and forget about it.” Did you mean “I’ll usually just include OSX and forget about it.” ?

2008-10-20
55ERROR

I think I’m missing something. In your example where you set the @logWindow.title, I keep getting the following error:

2008-08-30 11:15:42.013 Fenestra[794:10b] Controller#chooseApp: NoMethodError: undefined method `title=’ for nil:NilClass
\t/Users/berry/Documents/Fenestra/build/Debug/Fenestra.app/Contents/Resources/Controller.rb:24:in `chooseApp’

Line 24 in my error points to the following in your code:

@logWindow.title = entered

Were we supposed to set an ID for the window for this to work? I tried this as well, and it still doesn’t appear to work.

2008-10-20
55SUGGEST

Ok.. I found the reason it didn’t work. I didn’t assign the window to the logWindow in the interface builder. This should be clear in the book.

2008-10-20
12TYPO

line 6: “frameworkbecause” needs a space

2008-10-20
86TYPO

“stylized explanation points” -> “stylized exclamation points”

2008-10-20
95TYPO

“listens for distributed notificiations” -> notifications

2008-10-20
64SUGGEST

It may be a bit confusing to see constant (as you say) “Center” capitalized. It looks like a class name and generates questions. Since you already used a lower case “center” before it would be organic to continue using that local variable in your examples even without any side notes on where did it come from.

2009-01-08
69SUGGEST

It’s not clear why “Because you’ll rapidly get tired of typing ”com.exampler.counting" into
the text field, …". It looks like some link is missing.

2008-10-20
65ERROR

This is regarding the description of postNotificationName_object_userInfo method on the NSDistributedNotificationCenter.defaultCenter object.

When I wrote this, I originally believed there was an error in the book, however on further inspection, it appears there’s a tiny bug in Mac OS X.

According to the book, “the “object” that sends the message has to be a string that somehow names the sending app." For instance, “com.exampler.appname”

The “Name” isn’t described, but it appears to be the name of the notification.

So, for instance when running the Fenestra counting webapp and the Fenestra desktop app, creating an entry in the web app sends the following blob of text to the logs:

got distributed notification: NSConcreteNotification 0x57c890 {name = com.exampler.counting.create.after; object = com.exampler.counting; userInfo = {
creations = 1;
flash = “”;
name = blahblah;
}}

Where the Name is “com.exampler.counting.create.after” and the Object is “com.exampler.counting”.

This makes sense to me.

However, if you change the addObserver call to listen to all system events, and you fire one, say changing the Background, then you get the following notification in the logs:

got distributed notification: NSConcreteNotification 0x57c890 {name = com.apple.desktop; object = BackgroundChanged; userInfo = {
ChangePath = “/Library/Desktop Pictures/Nature”;
DApertureExpanded = 0;
DAppleExpanded = 1;
DFolders = (

}

This doesn’t make sense to me since it looks like name in this case is “com.apple.desktop” and the object is BackgroundChanged. In otherwords, it looks like those values should be switched.

If this is a small bug on Apple’s part, you may want to pick a different example to use in the book since seeing the values switched like that was just a bit confusing to follow along.

Of course, there may actually be no bug, and Apple is right, and I’ve just wasted both of our times.

2008-10-20
143TYPO

In the “My Solution” section it’s said: “That meant I needed a to make a new outlet …”.

An extra “a”?

2008-10-31
134ERROR

In this piece of code (and consequentially in the ‘preferred-list’ code sample) the ‘template.name’ has to be ‘@template.name’, but even this won’t save it from an exception.

def description
“<#{self.class}: #{@display_name}/#{@app_name} by #{template.name}” +
" favorite: #{@favorite}"
end

For some reason, the piece is called before the initialization (it seems during the TranslatorPreference.alloc call in Preferences.init) and the template is still nil, so template.name fails with an exception. My modifications to make it run are:

def description
template = template.nil? ? nil : template.name
“<#{self.class}: #{@display_name}/#{@app_name} by #{template}” +
" favorite: #{@favorite}"
end

It begs for some research and explanation though.

2008-12-24
144SUGGEST

Another possible way of dealing with NSRect (window frame) when saving / restoring it is to perform the transformation to/from array. To illustrate (given that ‘frame’ is NSRect):

  1. When saving, you convert it into array: [[x, y], [w, h]]
    frame_in_array = frame.to_a
  1. When restoring, you convert it back
    frame = NSRect.new(frame_in_array)

Quicker and cleaner, while using all standard means. Anyway, just a suggestion.

2008-10-31
169TYPO

“Drag an NSArrayController from the library into the log window.”

Didn’t you mean “doc window”?… If so, then the error is probably also on pages:
47 - “Worse, clicking on the Controller in the log window doesn’t get it back.”
155 - “dragging an NSObject into the log window.”
165 - “Notice that IB immediately creates an NSUserDefaultsController in the log window.”

2008-10-31
174TYPO

“If one asterisk is means a pointer” -> remove “is”

2008-10-31
174ERROR

“The word “id” is shorthand for “NSObject *”"

I think this is a bit misleading - someone may infer from this that id is really only a shorter way of writing the same thing, but it’s not - using id allows more dynamic typing without getting compiler warnings, and NSObject* will shout at you more often than id.

2008-10-31
186TYPO

On the lower picture: “A ooted keypath” (at least that’s how my Preview displays it…)

2009-01-08
191TYPO

“Like almost object templates” -> like almost ALL object templates?

2008-10-31
201TYPO

“Cocoa bindings are a three-layered technology.
Key-value binding
At the bottom, you have key-value binding, which is a way of making object properties more dynamic.”

Shouldn’t this say “key-value CODING” instead of “key-value binding”?

2008-10-31
191TYPO

“In the next chapter, we’ll add a PreferencesController to the preferences.xib Nib. The two Nibs will have separate PreferencesController objects, but bindings will keep them
synchronized via the shared NSUserDefaultsController.”

Did you mean MainMenu.nib? Because preferences.xib already has a PreferencesController, and MainMenu.nib hasn’t got it if I remember correctly…

And by the way, in the next chapter there aren’t any NIBs at all - you probably meant chapter 17 (which doesn’t exist yet).

2008-10-31
63TYPO

A space missing between two words (“NSApplication’s” & “terminate”):

“I think that NSApplication’sterminate method closes all open windows.”

2009-01-08
26SUGGEST

This may be considered nitpicky but thought I would suggest anyway.

In statusbar/speaking-statusbar.rb there is a variable named “item” in both App#applicationDidFinishLaunching and SpeechController#add_menu_to. Perhaps changing one to status_bar_item and the other to menu_item would be more descriptive. This way, in App#applicationsDidFinishLaunching the last three lines becomes more intuitive:

status_bar_item.setImage(image)
status_bar_item.setTitle(“foo”)
SpeechController.alloc.init.add_menu_to(status_bar_item)

2008-12-24
28SUGGEST

The numbering in the PDF’s Figure 3.3 restarts at (1), but the numbering in the .tgz continues at (5). I imagine this will be true every time you split a single source file into multiple figures; I’ll spare you the duplicate bug reports unless you want them.

2009-01-08
31SUGGEST

Incredibly nitpicky, but: Copperplate? Really? A bundle is a law firm? :)

2009-01-08
28OK

This example confused me a lot, and I finally realized why: SpeechController.add_menu_to has no business being there! More accurately, I suppose, you could say that the rest of it (speak) has no business being there; a Controller is a fine place to create a menu, but a lousy place to Do Things. Either way, if you’re trying to “separate concerns” and introduce MVC, combining menu creation with actions is confusing, especially when the menu itself has only two items, and one of them points at the application.

Also: item.setTarget(NSApp) is surprising. I tried adding

app = App.alloc.init

NSApp.setDelegate(app)

and that worked, but item.setTarget(app) complained about a selector. Are we going to find out later why that doesn’t work?

2009-01-08
22TYPO

It took a few reads to understand the relationship between AppDelegate, NSApp and NSApplication. I’m guessing that NSApplication.sharedApplication magically creates an object called NSApp by convention; we never ask for that name. It’d be nice to see that explicitly called out.

Next, we call NSApp.setDelegate(AppDelegate.alloc.init). If that were NSApp.setDelegate(AppDelegate.new), my eyes would see the connection, but I’m not yet used to .alloc.init, so it took me a few reads to realize that this was the magic link that made AppDelegate the main application.

I think this may be mooted by MacRuby; if not, consider something along the lines of

class AppDelegate < NSObject
..
end

app_delegate = OurApp.alloc.init

NSApplication.sharedApplication # creates NSApp
NSApp.setDelegate(app_delegate)

to make it more explicit the first time out.

2009-01-08
40TYPO

I created the project as instructed, but I didn’t see the main menu (1) or main window (2). They do appear when I double-click them from the doc window (3); maybe it depends on whether I’ve done stuff previously with IB?

2009-01-08
27TYPO

Only epub version. (pdf version is no problem.)
Beacause the background color of “Figure 2.1. Delegating Work” is black, I cannot see arrows in the Figure.
Some other figures have the same erratum.

2009-07-03
95SUGGEST

“”"

101SUGGEST

Add (new) subsection 8.1 called “A DSL FOR DELEGATIONS” since you really are covering a DSL like the current 8.1 (reborn as 8.2) which makes a great lead-in to the more complex “A DSL FOR NOTIFICATIONS”. This addition will structure the chapter a little better and give more room for discussing DELEGATIONS.

101TYPO

This chapter has great and valuable material in it. It brings out the best in ruby. Thank you.
However the approach is a bit of a deep dive into Ruby metaprogramming in sheeps clothing. The major pieces (files) are not displayed or explained, and it takes the reader some sleuthing offbook (i.e., online) in order to figure out what’s going on. As with my comment on chapter 7, I believe the book should be at least semi-independent.

I suggest beefing up the section on DELEGATION (and making it a first-class subsection as noted in my first comment on this chapter). Perhaps show Delegatable.rb and take a quick look at the hooks and mechanics that make this delegation DSL work.

For instance, why is Delegatable split into two modules. To the newer rubyist, that looks unnecessary. I gather from some sleuthing it’s actually necessary since the Delegatable::self.included hooks into a parent class, so that it can hook DelegatableClass into all the children. So the double module is necessary for the parent-child hooks. If so, that could bear explaining (or whatever is appropriate).

Some readers are not fully versed in ruby, and anything which requires multiple files or modules to implement probably warrants a little explanation to keep the determined readers rolling.

Thx.

101SUGGEST

Oops. Last comment should be a suggestion. Thx.

95SUGGEST

Hmm, first comment got lost in posting… Argh. (Apparently triple-quotes do not work in these comments?)

"

95TYPO

Hmm, first and second comments got lost in posting. Apparently, any quotations get lost in posting?

Hmm, first comment got lost in posting… Argh. (Apparently triple-quotes do not work in these comments?)

>

95SUGGEST

Hmm, third try at this suggeston. Frustrating. Apparently, dragging comment box bigger causes problems? (Or is it the quotation marks?)

Hmm, first comment got lost in posting… Argh. (Apparently triple-quotes do not work in these comments?)

>

95TYPO

Hmm, comments 1-4 got lost in posting. Apparently, any quotation marks or greater than signs get lost in posting?

-Here, a notification is posted to the default NSNotificationCenter. (I
aliased that to Center in the Controller superclass.) I used the con
stant AppChosen instead of a literal string because typos in con
stant names fail more obviously. I’ve defined it and related con
-stants in a new file, Constants.rb.

I think this chapter would benefit from displaying the key files alluded to above: Constants.rb and Controller.rb. These are key files to the files displayed. Including them in the book would make the book semi-self-sufficient which I think is a necessity for offline reading. Even today, books have the advantage that they do not require a computer. I think this book loses some of that value if it’s not semi-independent of a computer.

Also for those of us newer to ruby, it would be nice to have a few extra explanations when advanced ruby concepts or multi-file solutions (complexity) are engaged the first time. For this chapter, I had to go offbook and examine the files to figure out exactly what was going on. It was not overly complex, but the multi-file organization added some opacity that a little expose in the book could have clarified without much ado.

Thx.

95SUGGEST

Last comment (#5th attempt on page 95) should be a suggestion.

106SUGGEST

NotificationBox.rb uses case statement with “when …:”. Apparently, these are not valid Ruby 1.9 (though they work in 1.8). For forward compatibility, I suggest changing the “when …:” to “when … then”. That seems to work.

47SUGGEST

Note that if you are building this yourself (and you should), and drag the line from the outlet to the surrounding NSScrollView, everything will look fine, but when you save, then run your code from Xcode, you will get a puzzling error in the console that informs you that a selector was not found. The problem is that you hooked the outlet to the container view (NSScrollView) instead of the text view NSTextView. This is sufficiently puzzling that it deserves a second mention.

135TYPO

immoralized → immortalized

58SUGGEST

Typing in the text field doesn’t provide the immediate feedback suggested on a keystroke-by-keystroke basis. You have to end editing (i.e., press enter or tab to another field) for this to work.

70SUGGEST

To make this work, you have to:

sudo gem install ramaze

Also, this is where it is crucially important to be using the version of Ruby that ships with Leopard. I’ve set an alias to get to that Ruby as follows:

alias aruby=/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby

Then I can just do:

aruby start.rb

and everything is just hunky-dory.

46SUGGEST

in Interface Builder 3.2 the definition of actions and outlets has moved from the doc window to the library. In the classes tab you can select your new class and add your actions and outlets.

345TYPO

Bullet point 8 mentions `requireosx/cocoa` — there’s a space missing after “require”.

87SUGGEST

Some of the classes use `ib_outlets`, only `WindowController` uses the singular `ib_outlet`. I guess they’re aliased, but the difference was enough to raise my eyebrows. ;)

46TYPO

Seems IB changed a bit.. in item 3 and 4 refer to creating Actions and Outlets for the controller. Its no clear as to how this gets completed.. A little reading and I got to it. Thought it best to point out the reader’s experience (the novice) is taken off the target focus of the author’s intent.

49ERROR

I found that I had to name the file controller.rb (note the lowercase filename). When it was Controller.rb it was throwing all kinds of errors.

PnHrrBTciJERROR

This is one of the best tips on wiritng that I’ve come across (and I get lots of them coming into my mailbox all the time!).I’m going to apply it today!~Deborah,The Happiness Coach!

Categories: