100% found this document useful (3 votes)
28 views

Download Full Step into Xcode Mac OS X Development First Printing Edition Fritz Anderson PDF All Chapters

into

Uploaded by

brikaamundi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (3 votes)
28 views

Download Full Step into Xcode Mac OS X Development First Printing Edition Fritz Anderson PDF All Chapters

into

Uploaded by

brikaamundi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 71

Download the full version of the ebook at

https://ebookultra.com

Step into Xcode Mac OS X Development First


Printing Edition Fritz Anderson

https://ebookultra.com/download/step-into-xcode-
mac-os-x-development-first-printing-edition-fritz-
anderson/

Explore and download more ebook at https://ebookultra.com


Recommended digital products (PDF, EPUB, MOBI) that
you can download immediately if you are interested.

Mastering Mac OS X Third Edition Todd Stauffer

https://ebookultra.com/download/mastering-mac-os-x-third-edition-todd-
stauffer/

ebookultra.com

Mac OS X Lion Bible 1st Edition Galen Gruman

https://ebookultra.com/download/mac-os-x-lion-bible-1st-edition-galen-
gruman/

ebookultra.com

Mac OS X Programming 1st ed Edition Dan Sydow

https://ebookultra.com/download/mac-os-x-programming-1st-ed-edition-
dan-sydow/

ebookultra.com

Easy Mac OS X Lion 2nd Edition Kate Binder

https://ebookultra.com/download/easy-mac-os-x-lion-2nd-edition-kate-
binder/

ebookultra.com
Learning Unix for Mac OS X 1st Edition Dave Taylor

https://ebookultra.com/download/learning-unix-for-mac-os-x-1st-
edition-dave-taylor/

ebookultra.com

Mac OS X Developer s Guide 1st Edition Jesse Feiler

https://ebookultra.com/download/mac-os-x-developer-s-guide-1st-
edition-jesse-feiler/

ebookultra.com

Mac OS X Lion on Demand 2nd Edition Steve Johnson

https://ebookultra.com/download/mac-os-x-lion-on-demand-2nd-edition-
steve-johnson/

ebookultra.com

Cocoa programming for Mac OS X 2nd Edition Aaron Hillegass

https://ebookultra.com/download/cocoa-programming-for-mac-os-x-2nd-
edition-aaron-hillegass/

ebookultra.com

Using Mac OS X Snow Leopard 1st Edition Yvonne Johnson

https://ebookultra.com/download/using-mac-os-x-snow-leopard-1st-
edition-yvonne-johnson/

ebookultra.com
Step into Xcode Mac OS X Development First Printing
Edition Fritz Anderson Digital Instant Download
Author(s): Fritz Anderson
ISBN(s): 9780321334220, 0321334221
Edition: First Printing
File Details: PDF, 10.28 MB
Year: 2006
Language: english
Step into Xcode Mac OS X Development
ByFritz Anderson
...............................................
Publisher:Addison Wesley Professional
Pub Date: January 30, 2006
Print ISBN-10: 0-321-33422-1
Print ISBN-13: 978-0-321-33422-0
Pages:496

Table of Contents | Index

A Step-by-Step Guide to the Xcode Mac OS Development Environment

Every copy of Mac OS X comes with Xcode, the powerful development suite that Apple uses to
build applications ranging from Safari to iTunes. But because Xcode is complex and subtle,
even experienced Mac programmers rarely take full advantage of it. Now, Mac developer Fritz
Anderson has written the definitive introduction and guide to using Xcode to build applications
with any Macintosh technology or language.

Anderson helps you master Xcode's powerful text editor, industry-standard gcc compiler,
graphical interactive debugger, mature UI layout and object linkage editor, and exceptional
optimization tools. One step at a time, you'll develop a command-line utility, then use Xcode
tools to evolve it into a full-fledged Cocoa application. Anderson provides expert guidance on
development frameworks, source code management, Core Data modeling, localization, and
much more.

Coverage includes

Understanding Xcode workflow and the Mac OS X application lifecycle

Porting established legacy projects into Xcode

Using the Model-View-Controller design pattern to build robust graphical applications

Building static libraries and working with Xcode's build system

Making the most of bundles and package directories

Creating applications compatible with older versions of Mac OS X

Creating universal binaries to run on both Intel and PowerPC Macintoshes

Adding Spotlight searchability to data files

Leveraging Xcode's built-in support for unit testing

Using Xcode on makefile-based UNIX development projects


Step Into Xcode 's breadth, depth, and practical focus make it indispensable to every Mac
developer: current Xcode users upgrading to Xcode 2.1, experienced Mac programmers
migrating from CodeWarrior, UNIX/Linux programmers moving to Mac OS X, and even
novices writing their first programs or scripts.
Step into Xcode Mac OS X Development
ByFritz Anderson
...............................................
Publisher:Addison Wesley Professional
Pub Date: January 30, 2006
Print ISBN-10: 0-321-33422-1
Print ISBN-13: 978-0-321-33422-0
Pages:496

Table of Contents | Index

A Step-by-Step Guide to the Xcode Mac OS Development Environment

Every copy of Mac OS X comes with Xcode, the powerful development suite that Apple uses to
build applications ranging from Safari to iTunes. But because Xcode is complex and subtle,
even experienced Mac programmers rarely take full advantage of it. Now, Mac developer Fritz
Anderson has written the definitive introduction and guide to using Xcode to build applications
with any Macintosh technology or language.

Anderson helps you master Xcode's powerful text editor, industry-standard gcc compiler,
graphical interactive debugger, mature UI layout and object linkage editor, and exceptional
optimization tools. One step at a time, you'll develop a command-line utility, then use Xcode
tools to evolve it into a full-fledged Cocoa application. Anderson provides expert guidance on
development frameworks, source code management, Core Data modeling, localization, and
much more.

Coverage includes

Understanding Xcode workflow and the Mac OS X application lifecycle

Porting established legacy projects into Xcode

Using the Model-View-Controller design pattern to build robust graphical applications

Building static libraries and working with Xcode's build system

Making the most of bundles and package directories

Creating applications compatible with older versions of Mac OS X

Creating universal binaries to run on both Intel and PowerPC Macintoshes

Adding Spotlight searchability to data files

Leveraging Xcode's built-in support for unit testing

Using Xcode on makefile-based UNIX development projects


Step Into Xcode 's breadth, depth, and practical focus make it indispensable to every Mac
developer: current Xcode users upgrading to Xcode 2.1, experienced Mac programmers
migrating from CodeWarrior, UNIX/Linux programmers moving to Mac OS X, and even
novices writing their first programs or scripts.
Copyright
Many of the designations used by manufacturers and sellers to distinguish their products are
claimed as trademarks. Where those designations appear in this book, and the publisher was
aware of a trademark claim, the designations have been printed with initial capital letters or in
all capitals.

The author and publisher have taken care in the preparation of this book, but make no
expressed or implied warranty of any kind and assume no responsibility for errors or omissions.
No liability is assumed for incidental or consequential damages in connection with or arising out
of the use of the information or programs contained herein.

The publisher offers excellent discounts on this book when ordered in quantity for bulk
purchases or special sales, which may include electronic versions and/or custom covers and
content particular to your business, training goals, marketing focus, and branding interests. For
more information, please contact:

U. S. Corporate and Government Sales, (800) 382-3419, corpsales@pearsontechgroup.com

For sales outside the U. S., please contact:

International Sales, international@pearsoned.com

Visit us on the Web: www.awprofessional.com

The Safari® Enabled icon on the cover of your favorite technology book means the book is
available through Safari Bookshelf. When you buy this book, you get free access to the online
edition for 45 days.

Safari Bookshelf is an electronic reference library that lets you easily search thousands of
technical books, find code samples, download chapters, and access technical information
whenever and wherever you need it.

To gain 45-day Safari Enabled access to this book:

Go to http://www.awprofessional.com/safarienabled

Complete the brief registration form

Enter the coupon code IDML-RFIM-T1UD-F3M1-GLAW

If you have difficulty registering on Safari Bookshelf or accessing the online edition, please e-
mailcustomer-service@safaribooksonline.com.

Library of Congress Cataloging-in-Publication Data

Anderson, Fritz.
Step into Xcode : Mac OS X development / Fritz Anderson.
p. cm.
Includes bibliographical references and index.
ISBN 0-321-33422-1 (pbk. : alk. paper)
1. Operating systems (Computers)-Software. 2. Macintosh
(Computer)-Software. I. Title.
QA76.76.O63
005.4'465dc22 2005029875
Copyright © 2006 by Pearson Education, Inc.

All rights reserved. Printed in the United States of America. This publication is protected by
copyright, and permission must be obtained from the publisher prior to any prohibited
reproduction, storage in a retrieval system, or transmission in any form or by any means,
electronic, mechanical, photocopying, recording, or likewise. For information regarding
permissions, write to:

Pearson Education, Inc.


Rights and Contracts Department
75 Arlington Street, Suite 300
Boston, MA 02116
Fax: (617) 848-7047

Text printed in the United States on recycled paper at Courier in Stoughton, Massachusetts.

First printing, January 2006

Dedication
For Chrissl,

Nancy, Roger, and Sarah,

who all made this possible.


Preface
From the moment it first published Mac OS X, Apple Computer has made a complete suite of
application-development tools available to every Macintosh user. Since Mac OS X version 10.3,
those tools have been led by Xcode, the development environment that Apple's engineers use
to develop system software and such applications as Safari, iTunes, Mail, and iChat. These
same tools are in your hands.

A solid text editor with syntax coloring and API-based code completion

The industry-standard gcc compiler suite

A graphical, interactive debugger based on the GNU debugger (gdb)

A mature human interface (UI) layout and object-linkage editor for Carbon and Cocoa

Tools for gaining detailed insights into optimizing performance


Audience
I wrote this book for three types of readers.

1. Newcomers curious about the world of Mac OS X development

2. Experienced UNIX-family operating systems users who want an introduction to the Mac
OS X tool set

3. Xcode users wanting to supplement their techniques

Step into Xcode will not attempt to teach programming, a programming language, or any of
the Mac OS X programming frameworks; good books on those subjects have already been
written. My aim is to focus squarely on using the Xcode tool set. Most of the book uses one
example projectnot as a showcase for the programming techniques involved but as a
framework for how to do Mac development with these tools.

The CD-ROM accompanying this book provides the complete project directory bugs and all!for
each chapter. Many of the examples in this book follow the progress of an application project
that begins with a UNIX command line tool and progresses to a Core Databased application
with Spotlight support. As you follow along, you won't have to peck out every file and setting
yourself. The CD-ROM directory, Examples, includes a copy of the project at every major stage
of developmentat least one version for each chapter. You can simply copy the current example
project to your hard drive; the only errors are the ones I made deliberately.
Structure of the Book
Step into Xcode is divided into two parts. Part I introduces Xcode and Mac OS X development
against the background of developing a simple application from a BSD command line tool to a
Tiger-savvy Cocoa application taking advantage of Core Data and Spotlight.

Chapter 1 introduces Xcode with the obligatory "Hello, World" demonstration.

Chapter 2 demonstrates the typical Xcode workflow by building a command line tool that
will form the heart of the application we'll be building throughout Part I.

Chapter 3 moves from passive use of the Xcode debugger to active use, interrupting
program flow to examine the workings of a flawed application.

Chapter 4 shows what happens in compilation and linkage, both generally and in Mac OS
X.

Chapters 5,6, and 7 wrap our command line tool in a Cocoa graphical interface. The
Model-View-Controller design pattern is matched to the tools Xcode provides to
implement it.

Chapter 8 focuses on property lists, a must-know subject in Mac OS X development, and


shows how to create text macros for Xcode.

Chapter 9 moves our command line tool into a static library, showing how to build such a
library and how to integrate a dependent target with Xcode's build system.

Chapter 10 examines bundles and package directories. Most of the targets Xcode can
produce are varieties of bundles. We look at the ubiquitous Info.plist file.

Chapter 11 develops techniques for creating custom view classes for Cocoa and shows
how the development tools support them.

Chapter 12 extends the odyssey of our library from library to framework, showing how to
package a dynamic library and its headers for sharing or for embedding in an application.

Chapter 13 surveys the Xcode options in support of source code management systems.
We set up a local CVS (concurrent versions system) repository and put our project under
SCM (software configuration management) control.

Chapter 14 covers two scenarios for cross-development: creating applications compatible


with versions of Mac OS X earlier than your own and creating universal binaries to run on
both Intel and PowerPC Macintoshes.

Chapter 15 shows how to use the data modeling tool to generate a Core Data model for
our application. After converting our application to use Core Data, many development
tasks become a matter of using Interface Builder.

Chapter 16 examines the techniques used to add Spotlight searchability to our data files.

Chapter 17 finishes up our application with a localization and offers some thoughts on
dead-code stripping.

Part II goes deeper into Xcode usage.

Chapter 18 examines the Xcode human interface and explains how to use it to navigate
projects.
Chapter 19 considers Xcode from the point of view of a developer accustomed to using
CodeWarrior, examining the stumbling blocks on the way to conversion and showing how
to make the Xcode experience more familiar. At the end of the chapter, the notes on
controlling the export of symbols may be useful to non-CodeWarriors.

Chapter 20 looks at Xcode from the point of view of a developer accustomed to working
with makefiles. This chapter describes the build system beneath the IDE (interactive
development environment) and explains how you can customize and control it.

Chapter 21 goes deeper into the debugging tools and techniques introduced in Part I.

Chapter 22 shows how to make Xcode work faster.

Project Builder

Xcode 1.0 was released with Mac OS X version 10.3 (Panther) in September 2003
but has a much longer heritage. Xcode is a development of the Project Builder IDE
used for Mac OS X through 10.2 and for NeXTStep and the NeXT operating system
before that.

Xcode, the result of a rethinking of Project Builder, aimed at streamlining the work-
flow of the typical programmer. Improvements centered on searching and
managing large projects and speeding the edit-compile-link-debug cycle of
development. Xcode added

Code completion

Distributed builds

"Predictive" compilation, using idle CPU time to compile inactive source files in
the background

ZeroLink "lazy" linkage for fast launch times during development

"Fix-and-continue" compilation for changing code while it is running in the


debugger

Version 3 (and now 4) of the gcc compiler

A faster help system in a separate window, with its own search facilities

Speed improvements

Chapter 23 builds a simple AppleScript Studio application and considers Xcode's built-in
support for unit testing.

Chapter 24 shows how to use Xcode on a large open-source makefile-based project, and
how to apply Xcode's debugger and the Shark performance measurement tool to it.

Chapter 25 offers tips, traps, and observations that were left over from the rest of the
book.

Finally, there are two appendixes:


Appendix A reviews how to get the latest version of Xcode and how to install it.

Appendix B lists the major settings variables used by the Xcode build system.
Xcode Versions Covered
This book is based on Xcode version 2.1, released in June 2005, although this version will
probably vary from the one you will use, as Apple has not been timid about reworking Xcode
substantially as performance and usability issues arise. The overall strategies and approach
developed in this bookthe Xcode workflowwill be the same across Xcode versions. For details,
you may have to explore Xcode's menus, inspectors, and preferences; search its help system;
or ask on Apple's mailing list for Xcode users: http://lists.apple.com/mailman/listinfo/xcode-
users.

Most of the material in this book can also be applied to Xcode 1.5, the last version of Xcode for
Mac OS X 10.3.
Typographical Conventions
In this book, code excerpts, symbols, and literal text inputs are set off in this typewriter font.
In interactive text, such as at a terminal, the text you enter is shown in boldface typewriter
font. Boldfacing is also used to emphasize changes to a program listing.

Human-interface elements, such as menu items and button names, are set in boldface text
font. If elements are chained, such as hierarchical lists or menus, each level is set off
by arrows.

Notes are set off in gray boxes.

Sidebars

Sidebars, which contain short digressions on subjects of interest, are set off by
rules above and below.
Acknowledgments
This book was conceived by Ann Sellers at Addison-Wesley, and I hope I've lived up to her
confidence in offering me the opportunity to write it. Greg Doench brought the book through
editing and production. Lara Wysong was tireless in seeing the book into presentable shape;
Evelyn Pyle's copy edits made me look much smarter.

I'd like to acknowledge the help given by David Gleason and Matthew Formica of Apple for
responding to my questions. Matt nudged me into a couple of new directions, and although I
couldn't completely follow his lead, his guidance improved this book.

Here in Chicago, Bob Frank and Jon Rentzsch offered helpful suggestions. And Kate, Bess, and
Selena all showed faith.
Part I: The Life Cycle of a Mac OS X
Application
Chapter 1. Kicking the Tires

Chapter 2. Simple Workflow and Passive Debugging

Chapter 3. Simple Active Debugging

Chapter 4. Compilation: The Basics

Chapter 5. Starting a Cocoa Application

Chapter 6. A Cocoa Application: Views

Chapter 7. A Cocoa Application: Controllers

Chapter 8. Property Lists

Chapter 9. Libraries and Dependent Targets

Chapter 10. File Packages and Bundles

Chapter 11. Creating a Custom View

Chapter 12. Dynamic Libraries and Frameworks

Chapter 13. Version Control

Chapter 14. Cross-Development

Chapter 15. Using the Data Modeling Tools

Chapter 16. Spotlight

Chapter 17. Finishing Touches


Chapter 1. Kicking the Tires
Section 1.1. First Run

Section 1.2. Hello, World

Section 1.3. What Went Where

Section 1.4. Summary


1.1. First Run
Xcode is installed, and it's time to see what it looks like. Find Xcode in /Developer/Applications
and double-click its icon to launch it. If you're running Xcode for the first time, the New User
Assistant window, as seen in Figure 1.1, will be presented.

Figure 1.1. The New User Assistant. The dialog panels in this
assistant capture your preferences the first time you run Xcode.

[View full size image]

The default settings in this window are best for most purposes. Simply click the Next button in
each panel; in the last panel, click Finish. Every setting in the New User Assistant is accessible
through Xcode's Preferences window, so you won't be committing to anything.
FileVault and Xcode

If you are using Mac OS X's FileVault feature to encrypt your home directory, the
New User Assistant's default settings will slow the performance of Xcode
significantly. Compiling and linking an application requires a lot of successive reads
and writes to files, and if FileVault is on, each read and write will have to pass
through the encryption engine. As compiler objects are unlikely to disclose
significant secrets, this is wasted effort.

To avoid this problem, create new folders outside your home directory to hold
intermediate and final build products. One possible location is in the /Users/Shared
directory. In the second panel of the New User Assistant, select the radio buttons
Separate location for build products: and Separate location for
intermediate build files:, and use the Choose . . . buttons to designate the
nonhome directories.

If this is the first time you've run Xcode or this particular version, Xcode will automatically
show you the release notes for the current version. Apple release notes are always worth
readingthey are the only developer documentation written by Apple's engineers, and some
subtleties are found only in the release notesbut for now, close the window. To return to the
release notes, select Show Release Notes in the Help menu.
1.2. Hello, World
We want to get Xcode to do something for us, however minimal. By tradition, this means
building a terminal command that prints Hello, World. Select the New Project . . . command
from the File menu. Xcode presents the New Project Assistant, shown in Figure 1.2.

Figure 1.2. The New Project Assistant. Scroll down to Standard Tool,
select it, and click Next.

Xcode organizes your work around a project , a collection of files, tool settings, and targets . A
target designates the project files used to build a particular product and the tool settings to
apply. The most common kind of project, for building an application, has only one targetfor
building the application itselfbut more complex projects may have several targets: for libraries,
plug-ins, and small tools built ad hoc to test new components.

If you are coming to Xcode from CodeWarrior, the term target is used slightly
differently. An Xcode target corresponds more closely to the CodeWarrior concept of
a product. A CodeWarrior project typically has two targetsdebug and finalfor each
product. Xcode has only one targetcorresponding to the productand any variant in
building a target for debugging or release is a matter of build configurations .

Different target types require different tool settings and system libraries. Xcode eases the
process of configuring a new project by offering you a choice of the most common target types
for the first target in the project. We want to make a simple command line utility that runs in
Mac OS X's BSD UNIX subsystem. Scroll down the list to Command Line Utility and the
subitemStandard Tool (see Figure 1.2), select that item, and click Next.

The next panelNew Standard Tool Assistant (Figure 1.3)lets you name the project and place it
on your disk hierarchy. For this exercise, type HelloWorld in the upper text field to name the
project. The second field will echo what you type, designating ~/HelloWorld/ as the project
directory. This means that the directory HelloWorldwhich will be created if it isn't already
therewill hold your project file , named HelloWorld.xcodeproj, as well as the other files needed
to build your project's targets.

Figure 1.3. The New Standard Tool Assistant. To name a new project,
type the name of the project. The assistant automatically names a
new folder to enclose the project and its files.

Click the Finish button. Xcode creates the HelloWorld directory, copies some files into it, and
opens the project window (Figure 1.4). For a BSD command line tool, the project starts with a
main.c file for the tool's main() function, a HelloWorld.1 template file for the man page, and
theHelloWorld product, shown in red on the screen because Xcode can't find the file associated
with it, which is natural enough, as we haven't built it yet.
Figure 1.4. The HelloWorld project window. Names of files, arranged
in groups, appear in the Groups & Files column at left. The list at
right provides searchable details of whatever is selected in the
Groups & Files column.

[View full size image]

These files are shown in the large detail list in the right-hand portion of the project window.
The contents of the detail list are controlled by the selection in the Groups & Files column.
Selecting the first item under this heading selects the project, filling the detail list with every
file included in the project. Below the project icon are folder icons, representing subgroups of
files; clicking on a folder icon displays in the detail list only the files in that group.

To the left of the project and folder icons are the familiar disclosure triangles. Clicking on a
disclosure triangle opens a container in a list. Expanding a file group folder shows the names of
the individual files in the group.

If you've been exploring, click on the project icon at the top of the Groups & Files column to
restore the list of all files in the detail list under File Name. Now double-click main.c. A window
like the one in Figure 1.5 appears.

Figure 1.5. An editor window, showing the default main.c from the
Xcode command line tool template.

[View full size image]


The placeholder for main() in the default main.c for a command line tool is Hello, World. This
simplifies our first run of Xcode considerably. At the top of the window is a toolbar, the second
item of which is labeled Build and Go. Click that button. A minute may passthe first build of a
target is always longerbut you are soon rewarded with an output window (Figure 1.6) saying
Hello, World! Success.

Figure 1.6. The HelloWorld output window.

Quit Xcode (press command-Q, or select Quit Xcode in the Xcode application menu).
There's nothing to save, so the project and editor windows disappear immediately.
1.3. What Went Where
Switch to the Finder and examine the HelloWorld folder in your home directory (Figure 1.7).
TheHelloWorld directory is right where it was designated in the New Project Assistant and
contains the files HelloWorld.1 and main.c that came automatically with the new project. On
the screen, the blue HelloWorld.xcodeproj icon is the project document file; double-clicking it
opens Xcode and shows the HelloWorld project as you left it.

Figure 1.7. The HelloWorld project in the Finder. Creating and


building a command line tool project in Xcode created a folder for
the project, a project file, some template files, and a build directory
containing the completed tool.

[View full size image]

Thebuild directory contains the HelloWorld tool and a folder named Hello-World.build. This
folder contains a dozen files or so, including the compiled object code from main.c and a
number of files containing indexes to make it easier to navigate large projects and system
libraries. You can ignore the .build directory; its use is strictly internal in Xcode.

TheHelloWorld tool is a genuine UNIX executable, which you can demonstrate by using the
command line terminal. Open the Terminal application in the Utilities subfolder of the
Applications folder. Dragging the HelloWorld tool file's icon from the Finder into the Terminal
window has the effect of "typing" into the terminal the full path of what you dropped. Press the
Return key. The tool runs, prints Hello, World!, and returns to the command line prompt:

xcodeuser$/Users/xcodeuser/HelloWorld/build/Debug/HelloWorld
Hello, World!
xcodeuser$

Tools and applications built with the Debug build configuration, the default, are bound
uniquely to the computer that built them and won't run on other computers. We'll get
to this in Section 4.5.
At this point, we are done with the HelloWorld project. You can drag it and its files into the
trash. Xcode will show no sign of having built or run HelloWorld.
1.4. Summary
In this chapter, we

Ran Xcode and configured it for our use

Created a project to build a command line tool

Executed the tool from inside Xcode

Saw what Xcode does when it creates a project directory and builds a product in it

Verified that the tool we built will run from the command line

Disposed of the project when we no longer needed it


Chapter 2. Simple Workflow and Passive
Debugging
Section 2.1. Linear Regression

Section 2.2. Plan of Action

Section 2.3. A Command Line Tool

Section 2.4. Build Errors

Section 2.5. Simple Debugging

Section 2.6. Summary


2.1. Linear Regression
For most of this book, we'll be working on applications that do linear regression , a simple but
informative statistic. Suppose that you have a series of data pairs, such as the quarterly sales
figures for a particular department, shown in Table 2.1.

Table 2.1. Quarterly Sales Figures


for a Hypothetical Company
(millions of dollars)

Quarter Sales
1 107.5
2 110.3
3 114.5

4 116.0
5 119.3
6 122.4

Aregression line is the straight line that passes nearest all the data points (see Figure 2.1).
The formula for such a line is y = mx + b , or the sales (y) for a given quarter (x) rise at a
quarterly rate (m) from a base at "quarter zero" (b). We have the x and y values; we'd like to
determinem and b.

Figure 2.1. The sales figures from Table 2.1, plotted in a graph. The
line drawn through the data points is the closest straight-line fit for
the data.
The formulas for linear regression are as follows:

The value r is the correlation coefficient , a figure showing how well the regression line models
the data. A value of 0 means that the x and y values have no detectable relation to each other;
±1 indicates that the regression line fits the data perfectly.

Linear regression is used frequently in business and the physical and social sciences. When x
represents time, lines derived from regressions are trends from which past and future values
can be estimated. When x is volume of sales and y is costs, you can claim b as fixed cost and
m as marginal cost. Correlation coefficients, good and bad, form the quantitative heart of
serious arguments about marketing preferences and social injustice.

The demands on a program for turning a series of x and y values into a slope, intercept, and
correlation coefficient are not great: Keep a running total of x, x 2, y, y 2, and xy; keep note of
the count (n); and run the formulas when all the data has been seen.
2.2. Plan of Action
If you're an experienced programmer for UNIX operating systems, the solution to this problem
comes almost by impulse: Write a command line tool that reads data as pairs of floating-point
numbers from standard input and writes m,b, and r to standard output.

Here's the first draft of such a tool:

#include <stdio.h>
#include <math.h>

int main (int argc, const char * argv[]) {


int nScanned;
int n;
double sumX, sumY;
double sumX2, sumY2;
double sumXY;

n = 0;
sumX = sumY = sumX2 = sumY2 = sumY = 0.0;

do {
double x, y;
int nScanned = scanf("%lg %lg" x, y);
if (nScanned == 2) {
n++;
sumX += x;
sumX2 += x * x;
sumY += y;
sumY2 += y * y;
sumXY += x * y;
}
} while (nScanned == 2);
double slope, intercept;
slope = (n * sumXY - sumX * sumY)
/ (n * sumX2 - sumX * sumX);
intercept = (sumY - slope * sumX) / n;

double correlation;
correlation = slope * sqrt((n * sumX2 - sumX * sumX)
/ (n * sumY2 - sumY * sumY));

printf("%g\t%g\t%g\n", slope, intercept, correlation);

return 0;
}

Some veteran C programmers may be surprised to see declarations, such as double


slope, intercept, interspersed with executable statements instead of being gathered
at the top of the enclosing block. Declaring auto variables in the body of code is
permitted by gcc version 3 and later and has been added to the C99 language
standard.

Intermediate-level C programmers will see more than one error in this code. The
errors are intentional.
2.3. A Command Line Tool
Let's put this plan into action. Start Xcode. As you did in the previous chapter, select
Command Line Utility from the list of project types, and name the new project. We'll be
calling the new tool Linrg, so it's most convenient to give the same name to the project.

Once again, Xcode will present you with a project window set up for a BSD UNIX command line
utility. In Chapter 1, we double-clicked on the listing for the main.c file to bring up an editor
window for that file. This time, try clicking once on the main.c file name and then on the
Editor button in the project window's toolbar. The contents of the file appear in the right half
of the project window (Figure 2.2). Selecting different file names in the Groups & Files column
or in the detail list, display the contents of those files in the editor area.

Figure 2.2. Editing the Linrg tool. Note that the small icon next to the
file name main.c in the Groups & Files list and in the file name pop-
up is darkened, indicating that the file has unsaved changes.

[View full size image]

Whether you work in a separate editor windowor in an editor in the project window is
completely up to you. The two views are equivalent. The detail listing that formerly occupied
the right half of the project window is still available. You can have it back by clicking the Editor
toolbar icon again, or you can split the area between them by dragging the split bar that
appears above the editor view or below the detail view. Xcode makes frequent use of
completely closed split views, so be on the lookout for the telltale dimple in a thin bar at the
edge of a view.

The content of main.c is, as before, the Hello, World program, which isn't nearly so useful to us
this time. We substitute the source for our linear-regression tool, and click the Build button in
the toolbar. If you hadn't saved the file before building, a dialog offers to do so before
attempting the build; save the file. I've found that I always want to save changes before
building; by visiting the Building panel of the Preferences window, you can set the Unsaved
Files: pop-up to Always Save.
2.4. Build Errors
All has not gone well. The Xcode icon in the dock now has a red badge with a 1 in it. The status
bar at the bottom of the project window says "Build failed for target 'Linrg' (1 error)." At the
other end of the status bar is an error icon with the count of 1. Looking at the text of the
program, we see the same error icon at the left margin; holding the mouse cursor over the
icon brings up a tooltip saying, "error: parse error before 'x'." Sure enough, as we examine the
line marked by the icon (Figure 2.3), we find that we omitted the comma between the format
string and the second parameter to the scanf() call.

Figure 2.3. Error icon in the margin, from the first attempt at
buildingLinrg. When you point the mouse cursor at the icon, Xcode
pops up a tooltip describing the error.

Searching for errors by hand will not scale well to builds that span many errors among dozens,
or even hundreds, of files. Even Xcode's trick of placing black marks in the scroll bar to mark
the position of errors in the currently edited file only helps a little. Xcode provides a Build
Results window for browsing error messages that arise in the course of building a project. You
can see this window at any time by clicking the Build Results command in the Build menu or
pressingcommand-shift-B. You can also open the Build Results window by clicking the error
icons in the lower-right corner of any editor window.

Open the Build Results window now (Figure 2.4). The top half is taken up with an abbreviated
transcript of the build process, with the single error, "error: parse error before 'x'," highlighted
in red on the screen. Click the highlighted line. The editor view in the bottom half of the window
fills with main.c, centered on the line at which the error was detected.

Figure 2.4. The Build Results window, showing an error in Linrg's


main.c. Clicking the error line focuses the editor pane at the bottom
on the line at which the error was detected. Any file in Xcode can
have multiple editor panes open on it at one time.
It is common for Xcode to present editors for the same file in multiple windows. Source code
may be displayed in the Build Results window, the Project window, Editor windows, the
Debugger window, and even the Source Control window. In each case, the view is a full-
featured, writableto the extent that the target file is writable editor on the file in question. You
can make a change to a file wherever the file appears; Xcode knows that all the views are on
the same file, so there is no danger that the views will get out of sync.

With this in mind, use the editor in the Build Results window to insert a comma after the format
string, and click Build again. Now we are rewarded with the message "Build succeeded for
target 'Linrg'."

Note the cluster of four icons at the lower left of the upper panel of the Build Results window.
Clicking the icon that looks like a document with writing on it opens up the build transcript,
which details the commands used to accomplish the last build and the messages returned by
the tools. This transcript is worth looking at, first, for its value in showing how much goes on
behind the scenes in response to a single command. Second, in the course of advanced tuning
of the build process, this transcript is the only way to see what parameters are getting passed
to the compilers, linkers, and other tools and in what sequence. Third, although it is usually
very good at picking out the informative error messages from what its tools print out, Xcode
isn't perfect. Sometimes, looking at the transcript for the full message is the only way to make
sense of an error.

It's now time to run the Linrg tool. Hold the mouse button down on the Build & Go toolbar
item, and select Run from the drop-down menu. Xcode opens a Run Log window and awaits
our input.

For the first run, let's supply test data on the line y = 2x, adding a little bit of "noise" to make
things more interesting. Type the following into the Run Log window, and press Return:

1.0 2.05

Once again, we have a problem (Figure 2.5). The console prints out the message "Executable
'Linrg' has exited due to signal 10 (SIGBUS)," and the program stops. Mac OS X raises signals
10 (bus error) and 11 (segmentation violation) when a program tries to access memory in a
way that isn't permitted or that hasn't been allocated to its process. In a C program, this
almost always means that a proper value has not been supplied for a pointer.

Figure 2.5. The first runable build of Linrg crashes with a bus-access
error.
2.5. Simple Debugging
Although you may know what the problem with the Linrg tool is, let's prosecute this bug as
though it were a mystery. It is time to start debugging.

Xcode's interactive debugger is a windowed user interface for gdb, the GNU project's interactive
command line debugger. The command line interface to gdb is still available, through a console
window, but most debuggingespecially the simple kind we will do nowcan be done entirely
through the Xcode debugger window. The strategy here is simple: We'll run Linrg again, under
the supervision of the debugger, and let it show us where the crash occurs.

To run usefully under gdb, an application has to be built with settings that preserve information
that relates the binary in memory to the source codethe debugging flag, -gand ensure that the
binary being run works in the same sequence as laid out in the source: -00, the no-
optimization flag. We don't have to do anything to bring these settings about; they are set, by
default, in every new Xcode project.

If you've been following the Linrg example so far, the only thing you need to do is select
Debug Executable from the menu that drops down from the Build & Go toolbar item. If
you've made changes, select Build and Debug instead.

Xcode will take a few extra seconds to start gdb and display its Debug window before it has gdb
executeLinrg. Matters will come to a rest when Linrg is running and looking for data on
standard input.

If you've been using CodeWarrior, you are used to the debugger's pausing before the
first line of main(), waiting for your signal to proceed. Xcode sets no such automatic
breakpoints; if you need to do set-up tasks at the start of execution, you'll have to
set an early breakpoint yourself.

You will see that nothing new will be put into the Run Log window and that typing into that
window will have no effect. For applications being debugged, Apple has chosen to conduct all
standard input and output through a separate I/O window. Select Standard I/O Log from the
Debug menu to display this window: It won't appear automatically, and there is no toolbar
item available to make it visible.

Now, as before, type the following into the I/O window, and press Return:

1.0 2.05

This triggers the crash, but when crashing errors occur in a program being debugged, gdb stops
the program at the site of the crash, and the Xcode debugger displays the state of the
program. See Figure 2.6. The instruction that triggered the error is highlighted in red on the
screen and has a red arrowhead in the margin next to it.

Figure 2.6. The Xcode Debugger window as it appears when the bus
error in Linrg occurs. The machine instruction that caused the crash
is highlighted; the chain of function calls that led to this instruction
is listed in the upper-left panel.
[View full size image]

At first glance, the debugger seems to be doing us no favors: The offending line is highlighted,
yes, but the code in question is in assembly language and appears to be in a system-supplied
library. We were writing in C and were writing an application, not a system library.

Relief, however, is to be found in the panel at the upper left of the debugger window. This
panel lists the chain of function calls that led to the present execution state of the program
being debugged. The current function, _ _svfscanf, is at line 0. This function was called by
scanf (line 1), which in turn was called by main (line 2). This looks promising: We wrote a main
function and called scanf inside it.

CodeWarrior veterans will be used to the debugger's showing the call stack with the
most recent function at the bottom. Under gdb and the Xcode debugger, it's at the
top.

The Xcode debugger displays the first two function names in gray, but main is shown in black.
The debugger displays all function names in the call stack, for which it has access to source
code, in black. What happens if we click on main's item in the list?

The content of the Debugger window changes, most notably in the program listing at the
bottom (Figure 2.7). We recognize this as the main function we wrote. Execution of the
program was stopped inside the call to scanf, and the line containing that call is highlighted.

Figure 2.7. The Xcode debugger's lower, source code, display after
selectingmain in the stack trace. The line containing the call that led
to the place where the program halted is highlighted.
At this point, we can allow at least one scale to fall from our eyes: The scanf function requires
pointers to the variables it fills from standard input, not the values of those variables. As we
have found our error, there is nothing more for the crashed Linrg to tell us. Dispose of its
process by clicking the red Terminate item in the Debugger window's toolbar. Then edit the
line

int nScanned = scanf("%lg %lg", x, y);

to read

int nScanned = scanf("%lg %lg", &x,&y);

Now this bug, at least, is killed.


2.6. Summary
In this chapter, we chose a problem to solve with a computer program and devised a strategy
for solving that problem. We created a command line tool that does standard input and output.
We ran into a compilation error, saw how to get information on the error, and corrected it. We
saw how the Xcode debugger can be used passively to provide an instrument for examining the
state of a program when it has crashed and used the resulting insight to fix a bug.
Chapter 3. Simple Active Debugging
Section 3.1. The Next Step

Section 3.2. Active Debugging

Section 3.3. Summary


3.1. The Next Step
InChapter 2, we got the Linrg command line tool to build without errors and used the Xcode
debugger passively to track down and eliminate an early crashing bug. Let's run our tool again
and see how it goes. Make sure that the project is built, and select Debug Executable from
theBuild and Go menu in the Project window's toolbar.

Once again, we select Standard I/O Log from the Debug menu, so we can interact with
Linrg. Type some data:

1.0 2.05
nan nan nan

Well, after we enter two numbers and press Return,Linrg does not crash. It simply prints nan
nan nan and quits. The status bar in the Debugger and Project windows says, "Debugging of
Executable 'Linrg' ended normally."

Something else is wrong. An illegal floating-point operationsuch as dividing 0 by 0, or square-


rooting a negative numbertook place somewhere in our calculations, resulting in a NaN (not a
number), the special float value that signals an illegal operation. This need have happened only
once; any arithmetic done with a NaN results in a NaN, so a single illegal operation early in the
process could propagate the invalid-result marker through all subsequent calculations.

It makes sense that Linrg should report indeterminate results: Apparently, it tried to compute
the regression line after reading only one point, which is not enough to determine a line. We
suspect that this problem, then, is not in the computations but in the early exit from the input
loop.

The time-honored way to track down a bug like this is to put a printf() call after every
calculation, so that the problem code shows the state of the program at each significant step. If
the right things are printed at the right time, you can see where the application went off the
rails.

There is no need to instrument a step-by-step picture of Linrg's state, however, because we


have a computer to take care of that for us. The Xcode debugger will do everything we need.
3.2. Active Debugging
In our previous encounter with the debugger, it took control over Linrg when a fatal error
occurred. This time, we want the debugger to take control at a time of our choosing. By setting
a breakpoint at a particular line in Linrg, we tell the debugger to halt execution of the
application at that line, so that the contents of variables can be examined and execution
resumed under our control.

The easiest way to set a breakpoint is to click in the broad gutter area at the left margin of the
application source code in one of Xcode's editors. Select main.c in the Groups & Files list of the
main Project window to bring that file into the editing area. Scroll down to the first line of the
main() function if it isn't visible, and click in the gutter next to the line containing the command
n = 0 (Figure 3.1). On the screen, a long, dark-blue arrowhead appears in the gutter to show
that a breakpoint is set there. You can remove the breakpoint by dragging the arrowhead to
the side, out of the gutter; you can move the breakpoint by dragging it up or down the gutter.

Figure 3.1. Clicking in the gutter at the left margin of an editor area
to set a breakpoint at the adjacent line of code.

Clicking the breakpoint turns it pale gray and deactivates it without clearing it, which
is useful when more complex behaviors are attached to breakpoints. Control-clicking
the breakpointor right-clicking if you're using a two-button mousebrings up a menu
that allows you to remove, edit, or disable the breakpoint or to attach one of several
useful breakpoint actions. Breakpoint actions are discussed in Section 21.4.

SelectBuild and Debug from the Build and Go toolbar item in the main Project window, or
selectBuild and Debug (command-Y) from the Build menu. As before, Xcode performs any
tasks needed to bring the Linrg tool up-to-date, and starts running it. This time, however, the
Debugger window almost immediately shows that Linrg has halted at the breakpoint we set
(Figure 3.2).

Figure 3.2. The Debugger window as Linrg stops for a breakpoint at


the start of main(). The line at which execution paused is highlighted
in red on the sceen, and the current values of function arguments
and local variables are in the Value panel.

[View full size image]

Now we can take control. The top of the Debugger window consists of a toolbar (Figure 3.3)
that affords precise control over the execution of the program. The buttons and their actions
are as follows:

Build and Debug, available when the target application is not running, is a convenient
way to return to debugging after editing application source in the Debugger window's
editor pane.

Terminate halts the target application and ends debugging. When no program is
running, this button label is Debug and launches the current target under the debugger.

Fix allows you to make some changes in programs while they are running under the
Xcode debugger. This button compiles the file in the editor pane and attempts to patch
the file into the running process.

Restart halts the application being debugged and restarts it immediately under the
debugger. This saves time over terminating the application and restarting both the
debugger and the application.

Pause breaks execution of the target application wherever it happens to be.

Continue lets the target application continue running uninterrupted to the end or until it
encounters a breakpoint or an error condition.

Step Over lets the target application continue running until the next line in the function
currently executing, stepping over any function calls. If the current line is the last line of
the function, execution advances to the caller of the current function.

Step Into lets the target application run until the next line, whether it is in the current
function or in a function called in the current line. The debugger will step into function
calls.
Step Out lets the target application run until the current function returns.

Breakpoints opens a window listing all the breakpoints set in the current project. You
can add breakpoints by double-clicking in the label of the last, empty entry in the table
and typing the location for the new breakpoint.

Console opens a window that affords access to the command line features of the gdb
debugger, which underlies the Xcode debugger. This is the only way to access some
features of the debugger.

Figure 3.3. The toolbar of the Xcode Debugger window. The controls
in the toolbar allow you to start and pause execution of the program
being debugged or to step through the program line by line.
Specialized commands allow you to step into functions and methods
or to step out of the current function to its caller.

[View full size image]

Now we can step through Linrg one line at a time. To get a sense of this, scroll the variable
displayat the upper right of the Debugger windowdown so that the values of the sum...
variables are visible.

Now click the Step Over button a couple of times. The red highlight indicating the currently
executing line moves down the display of main.c in the Debugger window's editor; as you pass
the corresponding line, you see the values for sumX, sumY, and so on, change to 0.0. Whenever
an entry in the variable display changes in value, the new value is shown in red.

But wait. We see sumX,sumY, sumX2, and sumY2 get set to 0, but sumXY still displays in black the
junk value it had at the start. Did it get set? Will it? A quick examination of main.c in the editor
pane shows that we don't initialize sumXY. The line that should zero it out initializes sumY twice
instead.

Let's resolve to do something about that later. For now, we can force sumXY into good order by
double-clicking its value, typing 0.0, and pressing Return. The Xcode debugger and gdb, on
which it is based, allow you to set variable contents on the fly.

Another click of Step Over takes us to the line

int nScanned = scanf("%lg %lg", &x, &y);

We click Step Over at this line and find that Step Over is disabled. What's happening? This
line can't complete execution until the input of two floating-point numbers either succeeds or
fails. Awaiting input, scanf() blocks. To supply some, open the I/O log (Debug Standard
I/O Log), and again enter

1.0 2.05

PressReturn. The application is no longer blocked waiting for input; scanf() returns, and the
debugger can now honor our Step Over instruction by stopping at the next line.

Stepping slowly through the lines that follow, we see the progress of Linrg reflected in the
Exploring the Variety of Random
Documents with Different Content
Bess read it hastily, looked at her mother, and then read it again, slowly
and thoughtfully.

"Well?" asked her mother.

"Why, I'm not the one to decide," said Bess.

"What's up?" inquired Rob.

"Mr. Allen is going abroad for a year, and takes his wife with him,"
explained Mrs. Carter, "and he wants"—

"Cousin Bess to go too?" interrupted Rob so disconsolately that they all


laughed.

"Console yourself, my dear little cousin," said Bess. "He only wants us
to take Fred to board."

In his secret heart, Rob thought that was almost as bad. With Fred here
all the time, good-by to his pleasant walks and games with his cousin. He
was silent, but Bess read his thought.

"Don't worry, Robin, the house is plenty large enough for two boys, and
I'll not let Fred cut you out."

Mr. Allen's note was the perfection of tact. He spoke of his invalid son,
whose happiest hours were spent with the friend that had done so much to
brighten his dark life; he regretted the pressing business which called him
abroad just then, but Mrs. Allen's health, much shaken by sorrow for her
son, demanded a change and freedom from care. He went on to suggest
very delicately that it would be a great accommodation if Fred might board
with them; that Mary would be at hand to wait on him, to free them from
any restraint, while she could either board with them or come in at certain
hours; and, finally, that he should expect them to call on his coachman with
perfect freedom, during his absence.

"What do you think of it, Bess?" asked her mother again.

"Why, mother, you must decide. I am not the one."


"Yes, you are," replied her mother, "for it will make more difference to
you than to the rest of us. Fred would be largely under your care. Are you
strong enough to go through it?"

"I think I am," said Bess slowly. "I should like him here, if you and
father don't object. The boy has to learn all over again the very ABC of
living, and he has no one to teach him but us. Only, I don't want Mary."

"Who would take care of Fred, to give him what help he needs?" asked
Mr. Carter.

"I would," responded Bess promptly. "He doesn't need much, and it will
be less every day. Mary would be only an extra care and worry. She would
be half servant, half companion, and that would just upset Bridget. We don't
want her round in the way."

"I think you are right," said her mother. "But think this over carefully,
Bess. If you don't feel equal to it, don't try. I shall not be able to do much,
and it will make a great care for you."

"I know it, mother; but I think I can go through with it. Fred will be
happy with us, and Rob will help me with him, won't you, dear?"

"One thing more, Bess," said her father seriously. "If you start on this,
you must make up your mind not to give up all your time to the boy, even if
he does want you. You must go out, and walk, and make calls, as much as
ever. You are not going to turn hermit for a year in your devotion to one
small boy, however much good you may do him. And it would not do him
good, either. He must grow self-reliant and unselfish, and not feel that he
must be amused and waited on every moment."

As if to add his opinion to the family discussion, Fuzz, whose attention


was caught by the serious tones of their voices, jumped out of his basket,
and, coming to the side of his mistress, sat up on his haunches, and waved
his small paws in the air, as he swayed unsteadily from side to side in his
eagerness.

"What is it, Fuzz?" asked Rob, leaning over to pat his head.
Fuzz only replied with a snarl so emphatic that it showed his very back
teeth, and then turned again to Bess, and raised his paws higher than ever.

"Bess, that dog grows crosser every day," said her mother. "You really
ought to give him a hard whipping for snapping at Rob like that. What will
Fred do, with such a cross animal about?"

"He liked Fred, and if he is let alone I don't think there will be any
trouble," said Bess, ready to take up the cudgels in defence of her pet. "I
don't think he feels well to-night; he never snapped at Rob before."

"Fuzzy is a bad dog! Come here to grandma," said Mrs. Carter in slow,
measured tones, as she glared at the dog, who looked in her face for a
moment, and then turned his head away with a prodigious yawn. "Children,
you must not laugh. He never will mind then. Well, Bess, what do you
think? Shall we let Fred come?"

"Yes, I should like it so much, unless it would be unpleasant for you and
father. You know I threatened once before to adopt him. Does he want to
come?"

"They haven't, Mr. Allen says, told him anything about their plans, until
they could settle on something. Will you write to Mr. Allen, then?"

"Yes, I will write this evening. But come, Rob, we've time for just one
more game."

The note was written, and the next evening Mr. Allen called to arrange
for Fred's coming four days later. The boy was to be left in the care of Bess,
on whose judgment Mr. Allen felt he could rely. After an hour spent in
discussing various minor details, Mr. Allen said, as he rose to go,—

"We have said nothing to Fred as yet, Miss Carter, about this; so
suppose you tell him, that is, if you can spend time to-morrow to come
down for a few moments. And, in case I do not have time to call again, I
will say now how much Mrs. Allen and I feel indebted to you for taking our
son into your home."
And with a stately bow he was gone. "Did you ever see such an old
iceberg!" remarked Bess disrespectfully, as she returned to the parlor fire to
thaw herself out. "Between him and Mrs. Allen I should think Fred would
be thankful for any change. Next Tuesday! Well, there's a good deal to be
done between now and then. Shall you worry, mother, with a new son on
your hands?"

"Not at all," said her mother heartily. "He is not my property, anyway;
though if I see you going very wrong, I shall put in my word."

"Oh, do!" said Bess. "I feel half terrified at the thought of my
responsibility. Still, I think that, at least, I shall do as well as Mrs. Allen."

The next afternoon Fred lay stretched on the sofa in an unusually dismal
mood. The whole house was in a bustle; his mother and Mary had been up-
stairs all day, rummaging through closets and drawers, with not a moment
to spare for him; the fire had gone out in the grate, and there was no one
near to build him another; and, worst of all, Miss Bess had not been near
him for four days, while Rob had not been down for two weeks. Everybody
had forgotten him, and he wished he could forget himself. Oh, for
something to do! With nothing but eating and sleeping to break the
monotony, life was so dull. He envied the man whom he heard shovelling
coal into a neighbor's cellar. He could fancy just how he stooped and gave
his shovel a powerful push, raised it with one swing of his strong arms, and
tossed it down into the opening before him; only stopping occasionally to
wipe his forehead on his grimy sleeve. Fred felt to-day that he would give
up all his comfortable home, just to change places with that man for one
little hour, and be able to see and work.

"Lost in 'maiden meditation,' Fred?" asked Bessie's voice at his side.

The boy sprang up with a glad cry.

"Oh, Miss Bess! I didn't hear you come in. How glad I am you are
here!"

"I mustn't stay but a moment," said Bess, as she sat down on a mussy
pile of pillows and afghan. "How is your mother?"
"She's well; but she's awfully busy," replied Fred, leaning on the back of
a chair, with his chin in his hands. "I don't know just what is up, but I
haven't seen her since breakfast—at least, she hasn't been here," he added
hastily, for he was gradually giving up the old-time expression.

"I can tell you, if you wish to know," said Bess quietly. "She is going to
Europe next Wednesday with your father."

Fred's face became so blank with astonishment that she hastily went on.

"But you are not going to be left here to keep bachelor's hall, nor to go
with them. Instead, what do you say to coming to our house?"

There was no doubt of the answer. Too happy to speak, Fred dropped on
the sofa, and turned his face to Bess, while a bright flush rose in his cheeks.
At last he said,—

"Is it really true, Miss Bess? Can I? May I? It's too jolly!"

"So you like the idea? Can you stand it for a year, and not get
homesick?"

"Homesick?" echoed Fred in lofty scorn. "I guess not! When can I
come? Did you say a year?"

"You are to come next Tuesday afternoon at four o'clock, and you are to
stay about a year. And now I must run away home again, for I have ever so
much to do. But, first, let me straighten out this sofa. What a muss! Get up a
moment."

And Bessie shook up the pillows, folded the afghan, took Fred by his
shoulders and put him back in the old place, and was gone. At the gate she
was met by her attendant, Rob.

"What did he say?" inquired that youth, as she reappeared.

"Not very much, but I don't think he objected."


The next two days were as busy to Bess as they were long to Fred, who
no longer envied the coal-heaver. A room adjoining Bessie's was to be
given up to the boy, and she took much care and pleasure in arranging it.

"I feel just like a child with a new doll," she told her mother. "I want
this room to be just as pretty and inviting as if Fred could see it."

By Tuesday noon, the room was ready, even to the tiny vase on the
table, holding one pink rosebud.

"Boys do care for such things, though they don't say much about it,"
Bess told her mother and Rob, whom she had invited to inspect the results
of her labors. "That sofa is my especial delight, though," she added,
pointing to the broad, old-fashioned couch between two western windows,
where Fuzz lay serenely asleep on one of the cushions. "That can be Fred's
growlery, where he can retire whenever he feels cross. I trust he won't use it
often."

Two hours later, as the carriage came up the drive, Mrs. Carter stood
waiting on the steps, while Bess ran out to meet Fred. The boy, clinging to
Bessie's arm, came slowly up to the door.

"Welcome to your new home, Fred," said Mrs. Carter's voice.

And he answered as he gave her gentle face a great boyish kiss,—

"It's just splendid to come."

CHAPTER VII.

"AND WHEN THE FIGHT IS FIERCE."


After a week or two spent in making Fred feel at home and settled in his
new quarters, Bess suggested her next plan. It was after church one Sunday
night, and Bess was sitting with her hat still on, by the parlor fire, while
Fred and the Dominie were in a promiscuous pile on the rug, where Fred
had been eagerly listening for the familiar step on the walk outside. Since
he had been at the Carters', he had lost much of his fretful look, and seemed
better and brighter in every way. Mrs. Carter petted him, and talked with
him, giving him many little hints of the way in which he might even yet be
a useful, happy man; while her husband laughed and joked with him, and
occasionally teased him a little. But, after all, it was neither gentle Mrs.
Carter, nor her genial husband, to whom the boy turned for advice and
sympathy in every question that came up. To him, Miss Bess was the one
person in the world, and well might he feel so, for she was most unselfishly
kind to him. From the moment when, on leaving his room in the morning,
he met her at the door, ready to guide him down the unfamiliar stairs, until,
after he was all in bed, she came in to say a last good-night, she was
constant in her attentions to him, and adapted herself to his every mood,
bright and full of fun when he was blue, encouraging when he was
despondent, and with apparently nothing to do but read to him or talk with
him. When she went out, as she did nearly every afternoon, she always
came in with some amusing adventure or bit of boy news to tell him; and
while she was gone, he spent the time petting the dogs, and counting the
moments until her return. When her step was heard, he always started to the
door, and, as she reached it, he opened it before her, and stood smiling up at
her as she closed it, and, with an arm around his shoulders, swung him
about, and marched him back to the fire. And Bess learned to watch for this
greeting, and stepped more heavily as she came up the walk. Adoration,
even from a child, is pleasant to have.

To-night, as Bess sat there with Fuzz in her lap and Fred at her feet, she
was thinking back to that ill-fated day, just a year ago, when Rob had come
home and announced that Fred had won the school prize. Such a change in
the year! But the boy must not grow up in ignorance, even if he were blind.
At her suggestion, it had been agreed with his father that Fred was to begin
to have a few simple lessons again, of which Bess was to have the care.
"You know as well as I do, Miss Carter, what will make Fred happiest
and best. I leave him wholly to you," Mr. Allen had said.

The boy lay, his head pillowed on the dog's shaggy side, his face
anxiously turned towards Bess, as if trying to read her thoughts. Suddenly
she said,—

"Well, Fred, what do you say to our starting on our lessons to-morrow?"

"What do you mean, Miss Bess?" said the boy, sitting up.

"Only just this, that I think it is time you went back and took up a few
lessons again."

Fred rose to his feet and began to walk slowly up and down the room.

"How can I?" he asked sadly. "I don't see how I can study any more."

"This way, Fred," said Bess, as, putting down the dog, she went to join
him in his march; "from nine till twelve every day, I have time to give up to
it. We will shut ourselves up in a corner by ourselves, and I will read your
lessons over to you a few times, and then ask you questions about them.
You can do ever so much in that way; and we don't want you to stop all
study, even if you can't read to yourself. How does the idea strike you?"

"I like it," said the boy, whose face had been brightening again; "only it
won't be much fun for you."

"Never you mind about me, my laddie," said Bess cheerfully, "I will
look out for myself."

And so it came about that for two or three hours each morning, while
Mrs. Carter was busy about the household cares that not even her delicate
health had made her willing to resign to her daughter, Bess and the boy
settled themselves in the library, where Bess read aloud to the child,
explaining as she read, and he listened eagerly, delighted at being able to
break away from his forced inaction. Bess found him an apt pupil, and
added to their other studies many simple lessons in the natural sciences,
teaching the boy to understand the world around him, as well as to see it
through her eyes. As college was out of the question for the lad, she tried to
teach him just those facts that would be of the most interest and use to him,
throwing aside any formal "course" of study, and only endeavoring to
answer the questions that came up in the course of their readings. And such
questions! Any young, healthy boy of ordinary intelligence can ask a
surprising and perplexing number of questions; but Fred, shut up within
himself as he was, with plenty of time for quiet thought, surpassed them all,
and often sent his tutor on a wild search through encyclopædias and
dictionaries, for a clear explanation of some knotty point.

All this time Rob had been very neighborly, for it had always been his
habit to run in to see his cousin nearly every day; and for some time after
Fred came the two boys were on most harmonious terms. In spite of
everything, Rob was jealous of Fred, and would gladly have changed places
with him for the next year; but he kept this feeling to himself, with an
instinctive fear that it might make cousin Bess feel badly.

For Fred's own good, it seemed to Bessie that, first of all, his shyness
must be overcome; for, in spite of all her efforts to encourage him, he still
showed his aversion to going out or meeting people, and always fled to his
room when any one came to call. Accordingly, one evening Bess asked the
boys, Rob and his four friends, to come in for an hour, thinking that Fred
would enjoy it when once they were there. As the boys came in, with all
their laughter and fun, she turned to speak to Fred, but no Fred was there.

"I heard him go up-stairs a few moments ago," said her mother. "I will
go up and call him." She returned presently, looking rather anxious.

"He says he doesn't feel well, and has gone to bed. He doesn't want
anything," she said to Bess.

"Oh, dear!" said Bess, almost impatiently. "What will the boys think,
when I invited them to see him?"

But the boys were ready to forgive everything, and the evening's games
were pronounced a great success. As they went away, Rob lingered behind
for a moment, to ask Bess if she thought Fred really ill.
"Oh, no; nothing serious, if it is anything at all. He may have some little
headache, but I suspect it was just because he dreaded meeting you boys."

An hour later, as Bess went to her room, she stopped to listen at Fred's
door. All was quiet, and she concluded that the boy was asleep. But just as
she was falling into her first doze, she thought she heard a noise from the
next room. Raising herself on her elbow, she listened intently, and soon
caught the sound of a smothered sob. She quickly put on a wrapper and
slippers, and went into Fred's room.

"What is it, my boy? Are you ill?" she asked anxiously.

"Oh, Miss Bess"—and Fred's voice broke.

"What is it, dear?" asked Bess again.

"Nothing—only—I couldn't see the boys to-night—and—and"—

Bess sat down on the edge of the bed, and took the child's hand in hers.

"Is that the reason you ran away?"

"Yes."

"But, Fred, the boys came to see you."

"I know, Miss Bess, but when I heard them, I just couldn't stand it. They
are all so different from me, and I can't do anything at all, and—and I didn't
want them round. They didn't care."

"They did care, Fred; and I cared very, very much. It worries me to have
you hide when any one comes here. And I had asked the boys, you know."

"I know it; but, Miss Bess, you don't know how hard it is! That night at
church I just felt as if they were all looking at me, and would talk about me
as soon as I went home. It's the not knowing that's the worst. And when I
hear the boys, it seems as if I couldn't always be different from them."
"My poor little Fred," said Bess, as she passed her hand gently across
the boy's forehead, and hot, tear-swollen eyes, "I wish so much, as much as
you do, that it need not be so. But, Fred, half the battle lies, not in bearing
your trouble, but in making the best of it. It is so hard, but each time you try
it will grow easier. I read once of an old blind woman who called all the
good things that came to her 'chinks of light;' and perhaps, if we try very
hard, we shall find some 'chinks' for you."

"I wish you could," said the child, with a long, sobbing breath. "It's all
so dark."

"Well, dear, isn't Rob a 'chink'? You dreaded him at first, just as you do
Phil and Teddy now. But, now you are used to him, you enjoy his coming
in. Wouldn't it be so with the other boys?"

"'Tisn't so bad with just one, but when they are all here"—

"Yes, but if you had once seen them, Fred, to wear off a little of the
strangeness? It is a year that you have been away from them, but they are
just the same dear boys that you used to enjoy so much. And they are
fonder of you than ever, for they are all so sorry for you, and want to help
you."

"That's the worst of it," said Fred impatiently; "nobody can forget I'm
blind one single minute!"

"Do you remember, Fred," asked Bess, "when Bert sprained his ankle
two years ago? You boys went often to see him, and he enjoyed your
running in. He didn't expect you to forget that he couldn't step on his foot
for three or four weeks, did he?"

"Yes, I know that," admitted Fred; "but, after all, 'tisn't the same thing a
bit. He was going to get right over it, and be as well as ever, and I can't ever
do anything any more. Oh, Miss Bessie, I wish I could die and be through
with it!" And the hot tears rolled down on her hand, as it lay against his
cheek.
Poor Bess was at her wit's end. The boy was nervous and excited, and
she felt that she must quiet him, but she knew not what to say. His trouble
was too great, too real, to make light of it; and yet, now was the time, if
ever, to impress on him the idea that he could and must be a man, in spite of
it.

"'And win with them the victor's crown of gold,'"

she thought to herself, as she listened to Fred's convulsive sobs.

"My dear boy," she said very gently but firmly, as she put her arm
around him and drew him over against her shoulder, "I want you to try to
stop crying and listen to me. You say you can't ever do anything more, like
the rest of the boys, but you have one chance that Rob and the others have
not. One thing you can be now, while their turn hasn't come yet."

"What is it?" asked Fred wonderingly.

"A hero, dear. A brave boy, who will grow to be a braver man. We know
too well that you can never see again, but because you can't see, that is no
reason you should be a coward and want to die. We aren't put here, Fred,
just to have a good time; but instead, we are to make just as much of
ourselves as we can, with what is given us. Because you can't go to college,
or play baseball, or skate, you need not think there is nothing you can do.
Which is better, to be a great scholar and a strong, active man, or to bear
bravely a sorrow like yours, be cheerful in spite of it, and, in thinking how
to make people around you a little happier and better, forget your own loss?
I'm not hard in saying this, Fred, but I am looking years ahead, and telling
you what will make you the best and happiest man. Do you believe me?"

The boy's gesture was answer enough.

"What would you think, Fred," she went on, "of a soldier who, in his
first fight, ran away because he feared he might be hurt? I know you would
call him a coward, but isn't that about what you did to-night? It would,
perhaps, have hurt a little at first, but isn't it braver to face the pain now,
than to run away from it, and put it off till another time? And the next time
it would be just as hard, and a little bit harder. The boys had come up here
to see you, thinking you were all going to have a bright, pleasant time
together once more. In a way, they were as much your company as mine;
but you went off and left them, with never a thought of their
disappointment, you were so anxious to escape being hurt. Was that quite
worthy of my boy?"

"I suppose I'm cowardly and selfish," said Fred rather bitterly. "What
else?"

"A thoroughly wretched little boy," answered Bess quickly. "I am not
scolding you, Fred; only trying to help you. Now answer me frankly; if you
had come down to see the boys, even if you did find it hard, wouldn't you
have been happier now than you are as it is?"

"I suppose so," admitted Fred reluctantly. "But, truly, I didn't mean to be
hateful."

"Neither does the soldier who runs away from his place, but he isn't as
brave a man as the one who stays. But, Fred, you can do these very boys a
world of good, if you only try in the right way."

"How?"

"This way. If they can see you going about with them, patient and
uncomplaining in your great trouble, it will teach them to bear their little
ones in the same way. If they see you bright and cheerful, the old jolly Fred
they used to know and love, they will feel there is something worth living
for besides school and games. They will be more thoughtful and
considerate, and through helping you and each other they will come to help
every one who is in trouble. And you will be so much more happy, too. If
all this shyness were gone, so you needn't be in constant dread of meeting
some one besides ourselves and Rob, you could go out freely, take long
walks with me, and be with the boys. I want you to live, my boy, not so that
people will pity you for what you have lost, but admire you for what you
are in spite of it all. Isn't that the truer way for our hero to live?"

"I will try, Miss Bess," said Fred slowly. "I know I am a baby, but I
really do want to be brave."
"That is my dear Fred! The old Greeks used to say, 'Not to live, but to
live well.' We will take that for our motto, and hope that the day will come
when you can feel that your life has done as much good in the world as it
might have done if you could have seen us all."

As Bessie paused, the old clock in the hall slowly struck twelve. She
counted the strokes, and then said gently,—

"Now, my hero, beginning with this new day, we will try to live bravely
and well, and to make the very best of our lives. And when it is harder than
you can bear, come right to me, and we will talk it all over together and see
if we can't make it easier. I don't like to have you go off by yourself in this
way, as you did to-night. Haven't you been asleep at all?"

"I couldn't. I heard you come to the door, and I tried to keep still, for
fear you'd worry. I'm sorry I disturbed you, but I am so glad you came. You
do make things batter, somehow!"

"I am so glad," said Bess; "that is what I am for. But now I want you to
stop talking and go to sleep. Do you think you will?"

"I'll try," said the child, "but I don't feel much like it. My head aches a
little."

Bess laid her hand on his throbbing forehead.

"Your head feels so warm," she said. "You lie down and don't talk any
more, and I will bathe it a little. Perhaps that will make you sleepy."

She turned and shook up the pillows, and the child lay back with a
grateful sigh, as she gently rubbed and patted his face. For a time he was in
constant nervous motion, but he gradually became quiet. At length she
fancied he was asleep, and was just slipping noiselessly from the bed, when
he asked,—

"May I say one thing more, Miss Bess?"

"What is it, Fred?"


"I'd like to go for a little walk to-morrow; and may the boys come up
again next week?"

At breakfast the next morning, both Fred and Bess looked rather the
worse for their vigil; but, except for an increased gentleness on Fred's part,
and a little more careful attention on Bessie's, there was nothing to show
what had occurred, and the secret of their long talk remained all their own.
As they went to their lessons, Fred said,—

"I had such a good dream last night."

"What was it?" inquired Bess, as she opened the history they were
reading.

"It was after our talk, you know," Fred answered slowly, as if trying to
bring it back again. "I was at home once more, lying on the sofa crying, for
everything went wrong, and I was all alone. All of a sudden you came into
the room, and as you walked towards me, it grew lighter and lighter, till I
could see you just as well as ever,—nothing else in the room, only just you.
You looked exactly the way you did the last afternoon before I went to
Boston. You remember how you went down to see me, don't you? Well, you
had on the same dress and hat and everything you wore then, and you stood
looking down at me, kind of laughing. And then you said 'Come,' and put
out your hand to help me up. I stood up and felt so much better. I kept
looking at you, because that was all I could see, and it seemed so good to
see you again. Then you took my hand and led me out into the street, and
along ever so far, to a strange place; and then, all at once, I could see again
just the way I used to. But just as I was holding on to you, and looking at
the trees and houses and people, I waked up, and it was only a dream."

"Only a dream!" said Bess regretfully. "How I wish it were all true!"

"But it was just like seeing you once more," answered Fred, as he
slowly drew his chair to the fire; "and I feel just as if I had seen you
yesterday." Then, as he settled himself comfortably, he added, with a flash
of fun that reminded Bess of the old Fred,—
"Well, I s'pose if I were as well as I used to be, I shouldn't be here now.
That's one good thing!"

CHAPTER VIII.

KING WINTER.

If Fred had been the hero of one of the stories of good little boys, whose
pages our mothers and grandmothers used to bedew with salt tears, from the
hour of his midnight talk with Bess his whole character would have
undergone a sudden and miraculous change. But he was only a natural boy,
just starting to fight his own way against heavy odds, and his progress was
slow and tiresome. Though he forced himself to go out with Bess, and to
see the boys when they came to the house, he still had the old longing to
avoid them, and the old quick temper would flash out at Rob now and then.
But Bess, watching him closely, could see his struggle, and often rejoiced
over some victory too slight to attract the attention of any one else. With a
quiet word of suggestion or encouragement she helped the boy onward
when he was cross and discouraged, or let fall some expression of approval
to show that she appreciated his efforts to live well, as a hero should do.

The first meeting with the boys was a trying one on both sides. Sam, in
particular, was so anxious to make the most soothing remarks, that he well-
nigh overwhelmed Fred by his expressions of sympathy and solicitude. But
just as Fred felt he could endure it no longer, and must beat a retreat, Bert
came to the rescue with some well-timed question that turned the
conversation to less personal subjects. It was by no means the first time that
Bess had been grateful to Bert for his quick perception of danger signals in
the conversation, and she hastily followed his lead. But the hour the boys
spent together was rather a stiff one, for Fred was silent and shy, and the
boys had not the courage to approach him, as they felt, more strongly than
ever, the sad difference between them. It was with a sigh of relief that Fred
heard the door close behind them; and, returning to the parlor, he threw
himself wearily into a chair, while Fuzz climbed on his knee and licked his
face. A moment afterwards Bessie's hand was laid on his shoulder.

"In a brown study, Fred?" she asked gayly.

"Yes—no—I don't know," was the somewhat vague response.

"What is it now?" she inquired, as she bent over the fireplace to pile up
the scattered embers.

"Nothing, only I didn't enjoy the boys much," said Fred candidly. "And I
don't think they enjoyed me. Do you think we shall ever have any more fun
together, Miss Bess?"

"Yes, indeed, Fred! It will take a little while to make up for the year you
have lost. But be patient; the time will come, and come soon. Was it as bad
as you expected?"

"I am afraid it was," confessed Fred. "Sam was the worst of all."

"And yet he had no idea of it," said Bess. "He meant to say something
very kind, and we ought to find out what people really mean, before we
judge them. I don't believe that, except for Rob, one of the boys would give
up as much for your sake as Sam, in spite of his long words and queer
grammar. But come, we have our book to finish before bedtime."

January and February had come and gone with but little snow, and no
cold weather. But from the very first day March seemed determined to
make amends for this neglect. A week of cold, clear weather brought
glorious skating, and the boys revelled in it. After a day or two of the sport,
Rob, Ted, and Phil put their heads together, and, as a result of their
planning, one fine moonlight evening the trio appeared to Bess, who was
comfortably toasting her toes and holding Fuzz, while she read aloud to
Fred.

"Cousin Bess!" exclaimed Rob, breaking in on this cosy scene, "just


drop that old book and come with us! Fred doesn't want you half as much as
we do."

"Do come," echoed Phil persuasively. "It is splendid skating, and we


want you to come, too."

"But I don't know how to skate," demurred Bess, with an affectionate


glance at the fire.

"It's high time you did, at your age," said Rob saucily. "And it's no use
to beg off, ma'am, for I know you have some skates, even if you don't know
how to use them."

"Yes, we'll teach you," added Ted. "It's fine to-night, and we want you
to go like thunder—oh!" And he had the grace to blush over his last word.

"But my skates are dull," pleaded Bessie.

"We've had them sharpened," said Phil, triumphantly dangling them


before her eyes. "Sha'n't she go, Fred?"

Now Fred did want to hear the rest of the story, instead of passing a
lonely evening. For a moment his face clouded, but a sudden thought came
to him, that such a feeling was unworthy the hero he was trying to be, and
he said bravely,—

"Please go, Miss Bess. I truly wish you would, and you can tell me how
many times you fall down."

Bess had seen his struggle, and more than ever longed to stay with him;
but the boys were clamorous, so she yielded, and went with them.

She had told the truth when she had said she could not skate, for,
although she had owned her skates for ten years, she had not put them on as
many times. But she was naturally sure-footed, and, with the three boys to
help her, she was soon able to propel herself slowly across the smooth sheet
of ice, in spite of occasional collisions with the many skaters.

"But what makes me turn around?" she asked anxiously, after she had
repeatedly had the mortification of starting for some desired spot, only to
turn helplessly midway on her course, and drift aimlessly backwards, with
her puzzled face fixed on the starting-point.

"It's because you don't strike out evenly," said Teddy. "Now watch me,
and do as I do." And he glided away across the pond.

Bess tried to glide after him, but her left foot constantly ran away from
her right, and she could only toddle along in a series of short strokes, until
she once more turned her back on the coveted goal, and, after a brief slide,
stopped short, awaiting further instructions. It was a merry evening, and
before they left the ice, Bess had learned to appreciate the fascination of the
sport, while she retired amidst the congratulations of her three knights, who
vied with one another in sounding the praises of their apt pupil. For a few
days Bess made the most of her new accomplishment, and spent an hour or
two of each day on the pond, where she quickly learned to feel at home, and
at least could keep her face turned towards the object of her hopes. It was
provoking to watch the ease with which her friends slid past her, looking so
independent and sure of their footing; and Bess at first was tempted to give
up the struggle, which she felt was making her ridiculous. But Rob's
protestations encouraged her, and on the third day she ceased to be the new-
comer. Her successor was a tall youth who awkwardly put on his skates,
rose unsteadily to his feet, balanced himself for a moment, and then, with a
smile that said as plainly as words, "Conquer or die," struck out boldly, only
to land in an ignominious pile at her very feet. From that moment she felt
herself a veteran in the art of skating.

It was late the next afternoon when Bess with one of her friends reached
the pond. Their skates were soon on, and they struck out together into the
merry crowd of skaters. Bess looked about for her cousin and his boon
companions, who were nowhere to be seen, and then watched her friend,
who was moving away alone, her swaying figure outlined against the ruddy
sunset. Then, refusing all offers of assistance, she struggled up the pond,
against the strong wind that nearly blew her backward. Half-way up the ice
she paused, stood for a moment to catch her breath, and then, with the
breeze helping her, lazily slid back, almost to the dam at the lower end of
the ice. This performance she repeated several times, greatly to her own
satisfaction. At length, she had stopped to speak to a friend, when a sound
of mingled scraping and shouting made them both raise their eyes, and
glance up the ice. A peculiar apparition was bearing down upon them, as
they stood there in the gathering twilight. At first, they could make out little
but its outline, but as it came rushing nearer, it was revealed in all its
splendor. Four sleds, two red, one yellow, and one blue, had been lashed
together, two in front, two behind, and covered with a sort of platform of
boards, from the front of which rose a complicated system of bean-poles,
crossed and re-crossed, bearing a red and yellow horse-blanket, spread as a
sail. Seated in state on the four corners of this platform, each waving a
diminutive flag, sat Rob, Ted, Bert, and Phil, while on an inverted keg in
the middle stood Sam, blowing on a tin horn with such energy that his
crimson cheeks looked ready to pop, like an overheated kernel of corn.
There was no way to guide or stop this unwieldy ice-boat, when once it was
well under way. For a moment, Bess watched it in amusement, until her
friend suddenly exclaimed,—

"The dam! They don't think of it!"

True enough! They were rapidly approaching the edge of the ice;
beyond lay a strip of still, green water, before it took its final plunge down
on the rocks thirty feet below. The two women looked up the pond. There
was no one near to help, and, besides, what could any one do? The boys
were rushing to certain death; could it be that in the twilight they did not see
their danger? But at that moment Bess saw them spring up, run to their
improvised sail and try to pull it down, as if hoping in that way to check
their mad speed; but it was too firmly lashed to its place. Must she see them
drown? There was the one chance for them, and, straining her voice to the
utmost, she shouted: "Rob! Phil! Jump for your lives!" and then turned
away her head, not daring to look.

But the answering "All right" came ringing back to her, and, turning,
she saw five prostrate figures on the ice, and the sleds, blanket and all, just
sinking into the strip of dark water. Skating to the spot as quickly as she
could, she found four of the heroes ruefully picking themselves up: Rob
with a black eye, Phil with a cut lip, and Sam with a bloody nose, while Ted
was uninjured. But Bert still lay motionless, stunned by his fall.

You might also like