More with Less |
|
|
|
|
|
2 | (3) |
|
|
5 | (1) |
|
Your first Ruby expressions |
|
|
6 | (1) |
|
Math operations and comparisons |
|
|
6 | (1) |
|
|
6 | (1) |
|
|
7 | (1) |
|
Calling a method on an object |
|
|
8 | (4) |
|
Input, storage, and output |
|
|
12 | (1) |
|
|
13 | (1) |
|
|
14 | (1) |
|
|
14 | (1) |
|
|
15 | (1) |
|
|
15 | (1) |
|
|
16 | (2) |
|
Inspecting objects with the "inspect" and "p" methods |
|
|
18 | (1) |
|
Escape sequences in strings |
|
|
19 | (1) |
|
Calling "chomp" on the string object |
|
|
20 | (2) |
|
Generating a random number |
|
|
22 | (1) |
|
|
23 | (2) |
|
Converting strings to numbers |
|
|
25 | (1) |
|
|
26 | (3) |
|
The opposite of "if" is "unless" |
|
|
29 | (1) |
|
|
30 | (4) |
|
|
34 | (2) |
|
|
|
|
|
|
36 | (1) |
|
Calling methods you've defined |
|
|
37 | (1) |
|
|
38 | (1) |
|
|
38 | (4) |
|
|
42 | (1) |
|
Returning from a method early |
|
|
43 | (1) |
|
|
44 | (1) |
|
|
45 | (1) |
|
|
45 | (1) |
|
|
46 | (1) |
|
What's the difference between a class and an object? |
|
|
47 | (1) |
|
|
48 | (1) |
|
Creating new instances (objects) |
|
|
48 | (1) |
|
Breaking up our giant methods into classes |
|
|
49 | (1) |
|
Creating instances of our new animal classes |
|
|
50 | (1) |
|
Updating our class diagram with instance methods |
|
|
51 | (4) |
|
Local variables live until the method ends |
|
|
55 | (1) |
|
Instance variables live as long as the instance does |
|
|
56 | (2) |
|
|
58 | (1) |
|
Attribute accessor methods |
|
|
59 | (2) |
|
|
61 | (1) |
|
Attribute writers and readers |
|
|
62 | (7) |
|
Ensuring data is valid with accessors |
|
|
69 | (1) |
|
Errors---the "emergency stop" button |
|
|
70 | (1) |
|
Using "raise" in our attribute writer methods |
|
|
71 | (2) |
|
|
73 | (3) |
|
|
|
3 Relying on Your Parents |
|
|
|
Copy, paste... Such a waste... |
|
|
76 | (2) |
|
Inheritance to the rescue! |
|
|
78 | (2) |
|
Defining a superclass (requires nothing special) |
|
|
80 | (1) |
|
Defining a subclass (is really easy) |
|
|
81 | (1) |
|
Adding methods to subclasses |
|
|
82 | (1) |
|
Subclasses keep inherited methods alongside new ones |
|
|
83 | (1) |
|
Instance variables belong to the object, not the class! |
|
|
84 | (7) |
|
Bringing our animal classes up to date with inheritance |
|
|
91 | (1) |
|
Designing the animal class hierarchy |
|
|
92 | (1) |
|
Code for the Animal class and its subclasses |
|
|
93 | (1) |
|
Overriding a method in the Animal subclasses |
|
|
94 | (1) |
|
We need to get at the overridden method! |
|
|
95 | (1) |
|
|
96 | (2) |
|
|
98 | (3) |
|
Difficulties displaying Dogs |
|
|
101 | (1) |
|
|
102 | (1) |
|
Why everything inherits from the Object class |
|
|
103 | (1) |
|
Overriding the inherited method |
|
|
104 | (1) |
|
|
105 | (3) |
|
|
|
|
|
|
108 | (1) |
|
|
109 | (1) |
|
Creating new Employee instances |
|
|
110 | (2) |
|
Division with Ruby's Fixnum class |
|
|
112 | (1) |
|
Division with Ruby's Float class |
|
|
113 | (1) |
|
Fixing the salary rounding error in Employee |
|
|
114 | (1) |
|
Formatting numbers for printing |
|
|
115 | (1) |
|
|
116 | (3) |
|
Using "format" to fix our pay stubs |
|
|
119 | (1) |
|
When we forget to set an object's attributes... |
|
|
120 | (1) |
|
|
121 | (1) |
|
|
122 | (1) |
|
|
123 | (2) |
|
Arguments to "initialize" |
|
|
125 | (5) |
|
"initialize" and validation |
|
|
130 | (1) |
|
Call other methods on the same instance with "self" |
|
|
131 | (6) |
|
Implementing hourly employees through inheritance |
|
|
137 | (3) |
|
Restoring "initialize" methods |
|
|
140 | (1) |
|
Inheritance and "initialize" |
|
|
141 | (1) |
|
|
142 | (6) |
|
An inefficient factory method |
|
|
148 | (1) |
|
|
149 | (3) |
|
|
152 | (2) |
|
|
154 | (2) |
|
|
|
|
|
|
156 | (1) |
|
|
157 | (1) |
|
|
158 | (3) |
|
Looping over the items in an array |
|
|
161 | (1) |
|
|
162 | (3) |
|
Eliminating repetition... the WRONG way... |
|
|
165 | (2) |
|
|
167 | (1) |
|
Defining a method that takes blocks |
|
|
168 | (1) |
|
|
169 | (1) |
|
Flow of control between a method and block |
|
|
170 | (1) |
|
Calling the same method with different blocks |
|
|
171 | (1) |
|
Calling a block multiple times |
|
|
172 | (1) |
|
|
173 | (1) |
|
Using the "yield" keyword |
|
|
174 | (1) |
|
|
175 | (4) |
|
|
179 | (2) |
|
DRYing up our code with "each" and blocks |
|
|
181 | (3) |
|
Blocks and variable scope |
|
|
184 | (4) |
|
Our complete invoicing methods |
|
|
188 | (1) |
|
We've gotten rid of the repetitive loop code! |
|
|
188 | (3) |
|
Utilities and appliances, blocks and methods |
|
|
191 | (1) |
|
|
192 | (2) |
|
|
|
6 How Should I Handle This? |
|
|
|
A big collection of words to search through |
|
|
194 | (2) |
|
|
196 | (1) |
|
|
196 | (1) |
|
Safely closing the file, with a block |
|
|
197 | (1) |
|
Don't forget about variable scope! |
|
|
198 | (3) |
|
Finding array elements we want, with a block |
|
|
201 | (1) |
|
The verbose way to find array elements, using "each" |
|
|
202 | (1) |
|
Introducing a faster method... |
|
|
203 | (1) |
|
Blocks have a return value |
|
|
204 | (5) |
|
How the method uses a block return value |
|
|
209 | (1) |
|
|
210 | (1) |
|
A closer look at the block return values |
|
|
211 | (1) |
|
Eliminating elements we don't want, with a block |
|
|
212 | (1) |
|
The return values for "reject" |
|
|
213 | (1) |
|
Breaking a string into an array of words |
|
|
214 | (1) |
|
Finding the index of an array element |
|
|
215 | (1) |
|
Making one array that's based on another, the hard way |
|
|
216 | (1) |
|
Making one array based on another, using "map" |
|
|
217 | (2) |
|
Some additional logic in the "map" block body |
|
|
219 | (1) |
|
|
220 | (3) |
|
|
223 | (3) |
|
|
|
|
|
|
226 | (1) |
|
An array of arrays...is not ideal |
|
|
227 | (1) |
|
|
228 | (2) |
|
|
230 | (3) |
|
Hashes return "nil" by default |
|
|
233 | (1) |
|
Nil (and only nil) is "falsy" |
|
|
234 | (2) |
|
Returning something other than "nil" by default |
|
|
236 | (2) |
|
|
238 | (2) |
|
|
240 | (2) |
|
A mess of method arguments |
|
|
242 | (1) |
|
Using hashes as method parameters |
|
|
243 | (1) |
|
Hash parameters in our Candidate class |
|
|
244 | (1) |
|
|
245 | (1) |
|
|
245 | (1) |
|
Making the entire hash optional |
|
|
246 | (2) |
|
Typos in hash arguments are dangerous |
|
|
248 | (1) |
|
|
249 | (1) |
|
Using keyword arguments with our Candidate class |
|
|
250 | (1) |
|
Required keyword arguments |
|
|
251 | (4) |
|
|
255 | (3) |
|
|
|
|
|
|
258 | (1) |
|
|
259 | (1) |
|
|
260 | (1) |
|
|
261 | (1) |
|
|
262 | (2) |
|
Fixing the astronomer's program |
|
|
264 | (2) |
|
Quickly identifying objects with "inspect" |
|
|
266 | (1) |
|
Problems with a hash default object |
|
|
267 | (2) |
|
We're actually modifying the hash default object! |
|
|
269 | (1) |
|
A more detailed look at hash default objects |
|
|
270 | (1) |
|
Back to the hash of planets and moons |
|
|
271 | (1) |
|
Our wish list for hash defaults |
|
|
272 | (1) |
|
|
273 | (6) |
|
The astronomer's hash: Our final code |
|
|
279 | (1) |
|
Using hash default objects safely |
|
|
280 | (1) |
|
Hash default object rule #1: Don't modify the default object |
|
|
281 | (1) |
|
Hash default object rule #2: Assign values to the hash |
|
|
282 | (1) |
|
The rule of thumb for hash defaults |
|
|
283 | (1) |
|
|
284 | (2) |
|
|
|
|
|
|
286 | (1) |
|
The media-sharing app . . . using inheritance |
|
|
287 | (1) |
|
One of these classes is not (quite) like the others |
|
|
288 | (1) |
|
Option one: Make Photo a subclass of Clip |
|
|
288 | (1) |
|
Option two: Copy the methods you want into the Photo class |
|
|
289 | (1) |
|
Not an option: Multiple inheritance |
|
|
290 | (1) |
|
|
291 | (1) |
|
|
291 | (2) |
|
Mixins, behind the scenes |
|
|
293 | (4) |
|
Creating a mixin for comments |
|
|
297 | (1) |
|
|
298 | (1) |
|
A closer look at the revised "comments" method |
|
|
299 | (1) |
|
Why you shouldn't add "initialize" to a mixin |
|
|
300 | (2) |
|
Mixins and method overriding |
|
|
302 | (1) |
|
Avoid using "initialize" methods in modules |
|
|
303 | (2) |
|
Using the Boolean "or" operator for assignment |
|
|
305 | (1) |
|
The conditional assignment operator |
|
|
306 | (3) |
|
|
309 | (1) |
|
|
310 | (2) |
|
Comparable and enumerable |
|
|
|
|
|
|
312 | (1) |
|
A preview of the Comparable mixin |
|
|
313 | (1) |
|
|
314 | (1) |
|
Implementing a greater-than method on the Steak class |
|
|
315 | (1) |
|
|
316 | (1) |
|
We have a lot more methods to define... |
|
|
317 | (1) |
|
|
318 | (1) |
|
|
319 | (1) |
|
Implementing the spaceship operator on Steak |
|
|
320 | (1) |
|
Mixing Comparable into Steak |
|
|
321 | (1) |
|
How the Comparable methods work |
|
|
322 | (3) |
|
|
325 | (1) |
|
|
326 | (1) |
|
A class to mix Enumerable into |
|
|
327 | (1) |
|
Mixing Enumerable into our class |
|
|
328 | (1) |
|
Inside the Enumerable module |
|
|
329 | (3) |
|
|
332 | (3) |
|
|
|
|
|
Ruby's core classes and modules |
|
|
335 | (1) |
|
|
335 | (1) |
|
|
336 | (1) |
|
Listing available classes and modules |
|
|
337 | (1) |
|
Looking up instance methods |
|
|
338 | (2) |
|
Instance method documentation |
|
|
340 | (1) |
|
Arguments in call signatures |
|
|
341 | (1) |
|
Blocks in call signatures |
|
|
342 | (1) |
|
Read the docs for the superclass and mixins, too! |
|
|
343 | (3) |
|
|
346 | (2) |
|
Class method documentation |
|
|
348 | (1) |
|
Docs for a class that doesn't exist?! |
|
|
349 | (1) |
|
The Ruby standard library |
|
|
350 | (2) |
|
Looking up classes and modules in the standard library |
|
|
352 | (1) |
|
Where Ruby docs come from: rdoc |
|
|
353 | (2) |
|
What rdoc can deduce about your classes |
|
|
355 | (1) |
|
Adding your own documentation, with comments |
|
|
356 | (1) |
|
The "initialize" instance method appears as the "new" class method |
|
|
357 | (1) |
|
|
358 | (2) |
|
|
|
12 Handling the Unexpected |
|
|
|
Don't use method return values for error messages |
|
|
360 | (2) |
|
Using "raise" to report errors |
|
|
362 | (1) |
|
Using "raise" by itself creates new problems |
|
|
363 | (1) |
|
Exceptions: When something's gone wrong |
|
|
364 | (1) |
|
Rescue clauses: A chance to fix the problem |
|
|
365 | (1) |
|
Ruby's search for a rescue clause |
|
|
366 | (2) |
|
Using a rescue clause with our SmallOven class |
|
|
368 | (1) |
|
We need a description of the problem from its source |
|
|
369 | (1) |
|
|
370 | (3) |
|
|
373 | (2) |
|
Different rescue logic for different exceptions |
|
|
375 | (2) |
|
|
377 | (2) |
|
Specifying exception class for a rescue clause |
|
|
379 | (1) |
|
Multiple rescue clauses in one begin/end block |
|
|
380 | (1) |
|
Updating our oven code with custom exception classes |
|
|
381 | (1) |
|
Trying again after an error with "retry" |
|
|
382 | (1) |
|
Updating our oven code with "retry" |
|
|
383 | (2) |
|
Things you want to do no matter what |
|
|
385 | (1) |
|
|
386 | (1) |
|
Ensuring the oven gets turned off |
|
|
387 | (1) |
|
|
388 | (2) |
|
|
|
13 Code Quality Assurance |
|
|
|
Automated tests find your bugs before someone else does |
|
|
390 | (1) |
|
A program we should have had automated tests for |
|
|
391 | (2) |
|
|
393 | (1) |
|
MiniTest: Ruby's standard unit-testing library |
|
|
394 | (1) |
|
|
395 | (1) |
|
|
396 | (2) |
|
A closer look at the test code |
|
|
398 | (2) |
|
|
400 | (1) |
|
|
401 | (3) |
|
|
404 | (2) |
|
|
406 | (1) |
|
|
407 | (1) |
|
A better way to assert that two values are equal |
|
|
408 | (2) |
|
Some other assertion methods |
|
|
410 | (3) |
|
Removing duplicated code from your tests |
|
|
413 | (1) |
|
|
414 | (1) |
|
|
415 | (1) |
|
Updating our code to use the "setup" method |
|
|
416 | (3) |
|
|
419 | (3) |
|
|
|
|
|
|
422 | (1) |
|
|
423 | (1) |
|
Project directory structure |
|
|
424 | (1) |
|
Browsers, requests, servers, and responses |
|
|
425 | (1) |
|
Downloading and installing libraries with RubyGems |
|
|
426 | (1) |
|
Installing the Sinatra gem |
|
|
427 | (1) |
|
|
428 | (2) |
|
|
430 | (1) |
|
|
431 | (1) |
|
|
432 | (3) |
|
Making a movie list in HTML |
|
|
435 | (1) |
|
Accessing the HTML from Sinatra |
|
|
436 | (2) |
|
A class to hold our movie data |
|
|
438 | (1) |
|
Setting up a Movie object in the Sinatra app |
|
|
439 | (1) |
|
|
440 | (6) |
|
Looping over several movie titles in our HTML |
|
|
446 | (3) |
|
Letting users add data with HTML forms |
|
|
449 | (1) |
|
Getting an HTML form for adding a movie |
|
|
450 | (1) |
|
|
451 | (1) |
|
Cleaning up our form with an HTML table |
|
|
452 | (2) |
|
|
454 | (2) |
|
|
|
|
|
Saving and retrieving form data |
|
|
456 | (4) |
|
Setting the HTML form to send a POST request |
|
|
460 | (1) |
|
Setting up a Sinatra route for a POST request |
|
|
461 | (4) |
|
Converting objects to and from strings with YAML |
|
|
465 | (1) |
|
Saving objects to a file with YAML::Store |
|
|
466 | (1) |
|
Saving movies to a file with YAML::Store |
|
|
467 | (6) |
|
Finding the next available movie ID |
|
|
473 | (3) |
|
Using our MovieStore class in the Sinatra app |
|
|
476 | (1) |
|
|
477 | (1) |
|
Loading all movies from the MovieStore |
|
|
478 | (2) |
|
Loading all movies in the Sinatra app |
|
|
480 | (1) |
|
Building HTML links to individual movies |
|
|
481 | (3) |
|
Named parameters in Sinatra routes |
|
|
484 | (1) |
|
Using a named parameter to get a movie's ID |
|
|
485 | (1) |
|
Defining routes in order of priority |
|
|
486 | (3) |
|
Finding a Movie in the YAML::Store |
|
|
489 | (1) |
|
An ERB template for an individual movie |
|
|
490 | (1) |
|
Finishing the Sinatra route for individual movies |
|
|
491 | (6) |
|
|
497 | |