-
Notifications
You must be signed in to change notification settings - Fork 106
/
Copy pathruby-guide-en.html_
680 lines (680 loc) · 42.3 KB
/
ruby-guide-en.html_
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
<html>
<body>
<div class="stretcher">
<h3>Using the Prompt</h3>
<p>The blue window above is a Ruby prompt. Type a line of Ruby code, hit <em>Enter</em> and watch it run!</p>
<p>For example, try typing some math. Like: <code class="cmd">2 + 6</code></p>
<div class="answer">\d+</div>
</div>
<div class="stretcher">
<h3>Numbers & Math</h3>
<p>Good! You did a bit of math. See how the answer popped out?</p>
<p>Ruby recognizes numbers and mathematic symbols. You could try some other math like:</p>
<ul><li><code>4 * 10</code></li>
<li><code>5 - 12</code></li>
<li><code>40 / 4</code></li></ul>
<p>Sure, computers are handy and fast for math. Let's move on. Want to see your name reversed?
Type your first name in quotes like this: <code class="cmd">"Jimmy"</code></p>
<div class="answer">"(\w+)"</div>
</div>
<div class="stretcher">
<h3>Say Your Name Backwards</h3>
<p>Perfect, you've formed a <strong>string</strong> from the letters of your name. A string
is a set of characters the computer can process.</p>
<p>Imagine the letters are on a string of
laundry line and the quotes are clothespins holding the ends. The quotes mark the beginning and end.</p>
<p>To reverse your name, type: <code class="cmd">"Jimmy".reverse</code> (<em>Don't forget the dot!</em>)</p>
<div class="answer">"(\w+)"</div>
</div>
<div class="stretcher">
<h3>Counting the Letters</h3>
<p>You have used the <code>reverse</code> <strong>method</strong> on your name! By enclosing your name in
quotes, you made a string. Then you called the <code>reverse</code> method, which works on strings to flip
all the letters backwards.</p>
<p>Now, let's see how many letters are in your name: <code class="cmd">"Jimmy".length</code></p>
<div class="answer">\d+</div>
</div>
<div class="stretcher">
<h3>On Repeat</h3>
<p>Now, I'm sure by now you're wondering what any of this is good for. Well, I'm sure you've been to
a website that screamed, <em>Hey, your password is too short!</em> See, some programs
use this simple code.</p>
<p>Watch this. Let's multiply your name by 5. <code class="cmd">"Jimmy" * 5</code></p>
<div class="answer">"(\w+)"</div>
</div>
<div class="stretcher chapmark">
<h3>Hey, Summary #1 Already</h3>
<p>Let's look at what you've learned in the first minute.</p>
<ul>
<li><strong>The prompt.</strong> Typing code into the green prompt gives you
an answer from a red prompt. All code gives an answer.</li>
<li><strong>Numbers and strings</strong> are Ruby's math and text objects.</li>
<li><strong>Methods.</strong> You've used English-language methods like <code>reverse</code>
and symbolic methods like <code>*</code> (the multiplication method.) Methods are action!</li>
</ul>
<p>This is the essence of your learning. Taking simple things, toying with
them and turning them into new things. Feeling comfortable yet? I promise you are.</p>
<p>Okay, let's do something uncomfortable. Try reversing a number: <code>40.reverse</code></p>
<div class="stdout">NoMethodError: undefined method `reverse' for (\d+):Fixnum</div>
</div>
<div class="stretcher">
<h3>Stop, You're Barking Mad!</h3>
<p>You can't reverse the number forty. I guess you can hold your monitor up to the
mirror, but reversing a number just doesn't make sense. Ruby has tossed an error
message. Ruby is telling you there is no method <code>reverse</code> for numbers.</p>
<p>Maybe if you turn it into a string: <code class="cmd">40.to_s.reverse</code>.</p>
<div class="answer">\"(\d+)\"</div>
</div>
<div class="stretcher">
<h3>Boys are Different From Girls</h3>
<p>And numbers are different from strings. While you can use methods on any object
in Ruby, some methods only work on certain types of things. But you can always
convert between different types using Ruby's "to" methods.</p>
<ul><li><strong>to_s</strong> converts things to <strong>s</strong>trings.</li>
<li><strong>to_i</strong> converts things to <strong>i</strong>ntegers (numbers.)</li>
<li><strong>to_a</strong> converts things to <strong>a</strong>rrays.</li>
</ul>
<p><em>What are arrays?!</em> They are lists. Type in a pair of brackets: <code class="cmd">[]</code>.</p>
<div class="answer">\[\]</div>
</div>
<div class="stretcher">
<h3>Standing in Line</h3>
<p>Great, that's an empty list. Lists store things <strong>in order</strong>.
Like standing in line for popcorn. You are behind someone and you wouldn't
dream of pushing them aside, right? And the guy behind you, you've got a
close eye on him, right?</p>
<p>Here's a list for you. Lottery numbers: <code class="cmd">[12, 47, 35]</code>.</p>
<div class="answer">\[(\d+(, )?){2,}\]</div>
</div>
<div class="stretcher">
<h3>One Raises Its Hand</h3>
<p>A list of lottery numbers. Which one is the highest?</p>
<p>Try: <code class="cmd">[12, 47, 35].max</code>.</p>
<div class="answer">(\d+)</div>
</div>
<div class="stretcher">
<h3>Tucking a List Away</h3>
<p>Good, good. But it's annoying to have to retype that list, isn't it?</p>
<p>Let's save our numbers inside a <code>ticket</code> like so: <code class="cmd">ticket = [12, 47, 35]</code></p>
<div class="answer">\[(\d+(, )?){2,}\]</div>
</div>
<div class="stretcher">
<h3>Now Type Ticket</h3>
<p>Now, type: <code class="cmd">ticket</code></p>
<div class="answer">\[(\d+(, )?){2,}\]</div>
</div>
<div class="stretcher">
<h3>Saved, Tucked Away</h3>
<p>Fantastic! You've hung on to your lotto numbers, tucking them away inside a
<strong>variable</strong> called <code>ticket</code>.</p>
<p>Let's put your lotto numbers in order, how about? Use: <code class="cmd">ticket.sort!</code></p>
<div class="answer">\[(\d+(, )?){2,}\]</div>
</div>
<div class="stretcher chapmark">
<h3>Summary #2 is Upon Us</h3>
<p>You had a list. You sorted the list. The <code>ticket</code> variable is now changed.</p>
<p>Did you notice that the <code>sort!</code> method has a big, bright exclamation at the end?
A lot of times Ruby methods shout like that if they alter the variable for good. It's nothin
special, just a mark.</p>
<p>Now, look how your second minute went:</p>
<ul>
<li><strong>Errors.</strong> If you try to reverse a number or do anything fishy,
Ruby will skip the prompt and tell you so.</li>
<li><strong>Arrays</strong> are lists for storing things in order.</li>
<li><strong>Variables</strong> save a thing and give it a name. You used the
equals sign to do this.<br>Like: <code>ticket = [14, 37, 18]</code>.</li>
</ul>
<p>In all there are eight lessons. You are two-eighths of the way there!
This is simple stuff, don't you think? Good stuff up ahead.</p>
<p>Let's change directions for a moment. I've stuffed a bit of poetry for you in
a certain variable. Take a look. Type <code class="cmd">print poem</code></p>
<div class="load">poem = "My toast has flown from my hand\nAnd my toast has gone to the
moon.\nBut when I saw it on television,\nPlanting our flag on Halley's
comet,\nMore still did I want to eat it.\n"</div>
<div class="stdout">My toast (.+)</div>
</div>
<div class="stretcher">
<h3>Sadly, You Hate Toast Poetry</h3>
<p>Look, it's okay. You don't have to like it. Hack it up, be my guest.</p>
<p>Instead of toast, go for a melon or something. Try this: <code class="cmd">poem['toast'] = 'honeydew'</code></p>
<p>And then type <code class="cmd">print poem</code> by itself to see the new poem.</p>
<div class="stdout">My honey(.+)</div>
</div>
<div class="stretcher">
<h3>Ready, Aim</h3>
<p>The square brackets you just used are very common in Ruby. Remember, you typed: <code>poem['toast'] = 'honeydew'</code>. That box with the word <em>toast</em> has a square bracket on each side, see?</p>
<p>The
two brackets are like sights used to line up a target. Exactly. These
brackets mean, "I am looking for ____." Ready, aim. Here you're looking
for toast and swapping it out with fruit.</p>
<p>Here's a question: what happens when we reverse this whole poem? <code class="cmd">poem.reverse</code>
</p><div class="answer">"\\n.ti tae ot (.+)"</div>
</div>
<div class="stretcher">
<h3>Too Much Reversal</h3>
<p>Okay, sure. So the whole poem's been turned backwards, letter-by-letter. I really want to just
reverse the lines, though. Move the last line up to first and the first line down to last. Backwards, but not
<em>that</em> backwards.</p>
<p>Here's how: <code class="cmd">poem.lines.to_a.reverse</code></p>
<div class="answer">\["More still did I(.+)"\]</div>
</div>
<div class="stretcher">
<h3>Ringlets of Chained Methods</h3>
<p>So what do you see? What happened there? You typed <code>poem.lines.to_a.reverse</code> and what happened?</p>
<p>Two things happened. You turned the <code>poem</code> into a
list using <code>lines.to_a</code>. <code>lines</code> decides the way
the string is split up, then <code>to_a</code> converted it into an
Array. (<strong>To a</strong>rray.) Different methods, such
as <code>bytes</code> and <code>chars</code> can be used in place
of <code>lines</code>. By using lines, ruby will return each line of the poem.</p>
<p>Then, you <code>reverse</code>d that list. You had each line. You reversed them. That's it.</p>
<p>Let's tack one more method on the end there: <code class="cmd">print poem.lines.to_a.reverse.join</code>
</p><div class="stdout">More still did I(.+)</div>
</div>
<div class="stretcher chapmark">
<h3>Of All the Summaries, #3 is Here Now</h3>
<p>Good show, my friend! The <code>join</code> method took that list of reversed lines and put them
together into a string. (Sure, you could have also just used <code>to_s</code>.)</p>
<p>Review time.</p>
<ul>
<li><strong>Exclamations.</strong> Methods may have exclamations (and also question marks)
in their name. No big deal. Try: <code>poem.include? "my hand"</code></li>
<li><strong>Square brackets.</strong> Target and find things. Search and replace.</li>
<li><strong>Chaining</strong> methods lets you get a lot more done. Break up a poem,
reverse it, reassemble it: <code>poem.lines.to_a.reverse.join</code></li>
</ul>
<p>At this point, you may want to tinker with the poem a bit more. A complete list of all
the <code>String</code> methods is
<!--<a href="http://www.whytheluckystiff.net/ruby/pickaxe/html/ref_c_string.html" target="_new">here</a>.-->
<a href="http://ruby-doc.org/core/classes/String.html" target="_blank">here</a>.
Go ahead and try a few (such as <code>poem.downcase</code> or <code>poem.delete</code>.)</p>
<p>When you're ready to move on, type: <code class="cmd">books = {}</code></p>
<div class="answer">\{\}</div>
</div>
<div class="stretcher">
<h3>A Wee Blank Book</h3>
<p>You've made an empty <strong>hash</strong>. (Also known as: an empty <em>dictionary</em>.)</p>
<p>We're going to stuff some miniature book reviews in this hash. Here's our rating system:</p>
<ul>
<li><code>:splendid</code> → a masterpiece.</li>
<li><code>:quite_good</code> → enjoyed, sure, yes.</li>
<li><code>:mediocre</code> → equal parts great and terrible.</li>
<li><code>:quite_not_good</code> → notably bad.</li>
<li><code>:abysmal</code> → steaming wreck.</li>
</ul>
<p>To rate a book, put the title in square brackets and put the rating after the equals.</p>
<p>For example: <code class="cmd">books["Gravity's Rainbow"] = :splendid</code></p>
<div class="answer">:\w+</div>
</div>
<div class="stretcher">
<h3>More Bite-Size Reviews</h3>
<p>Keep going, fill it up with reviews. And, if you want to see the whole list,
just type: <code>books</code></p>
<p>Again, the ratings are: <code>:splendid</code>, <code>:quite_good</code>, <code>:mediocre</code>,
<code>:quite_not_good</code>, and <code>:abysmal</code>.</p>
<p>These ratings are not strings. When you place a colon in front of a simple word, you get a
<strong>symbol</strong>. Symbols are cheaper than strings (in terms of computer memory.) If
you use a word over and over in your program, use a symbol. Rather than having thousands of
copies of that word in memory, the computer will store the symbol only <em>once</em>.</p>
<p>Once you've got <strong>three</strong> or <strong>four</strong> books in
there, type: <code class="cmd">books.length</code>.</p>
<div class="answer">[3-9]</div>
</div>
<div class="stretcher">
<h3>Wait, Did I Like <em>Gravity's Rainbow</em>?</h3>
<p>See, the <code>length</code> method works on strings, list and hashes. One great thing about
Ruby is that names are often reused, which means fewer names you need to remember.</p>
<p>If you'd like to look up one of your old reviews, again put the title in the square. But leave off
the equals.</p>
<p>Just like this: <code class="cmd">books["Gravity's Rainbow"]</code></p>
<div class="answer">:\w+</div>
</div>
<div class="stretcher">
<h3>Hashes as Pairs</h3>
<p>Keep in mind that hashes won't keep things in order. That's not their job. It'll just pair up two
things: a <strong>key</strong> and a <strong>value</strong>. In your reviews, the key is the book's
title and the value is the rating.</p>
<p>If you want to just see the titles of the books you've reviewed: <code class="cmd">books.keys</code></p>
<div class="answer">\[".*"\]</div>
</div>
<div class="stretcher">
<h3>Are You Harsh?</h3>
<p>So are you giving out harsh, unfair reviews? Let's keep score with this hash:<br><code class="cmd">ratings = Hash.new {0}</code></p>
<p>Then, okay, now let's count up your reviews. Just stay with me. Type:<br>
<code class="cmd">books.values.each { |rate| ratings[rate] += 1 }</code></p>
<p><em>(The straight line in the code is the pipe character, probably located right above the
Enter key on your keyboard.)</em></p>
<div class="answer">\[:.+\]</div>
</div>
<div class="stretcher">
<h3>A Tally</h3>
<p>Great, wow! You've made a scorecard of your ratings. Type <code>ratings</code> to see the count.
This new hash shows a rating and then the number of times you've given that rating.</p>
<p>One of the amazing new things we've just used is a <strong>block</strong>. We're going to
explore these more in the next summary. But, basically, a block is a bit of Ruby code surrounded
by curly braces.</p>
<p>Let's try another block: <code class="cmd">5.times { print "Odelay!" }</code></p>
<div class="stdout">Odelay!Od.*</div>
</div>
<div class="stretcher chapmark">
<h3>Now Arriving at Summary #4</h3>
<p>Blocks are always attached to methods. Like the <code>times</code> method, which takes the
block and runs the code over and over. (In this case: <strong>five</strong> times.)</p>
<p>This last lesson was a bit longer. You've probably used up three minutes learning about:</p>
<ul>
<li><strong>Hashes.</strong> The little dictionary with the curly pages: <code>{}</code>.</li>
<li><strong>Symbols.</strong> Tiny, efficient code words with a colon: <code>:splendid</code>.</li>
<li><strong>Blocks.</strong> Chunks of code which can be tacked on to many of Ruby's methods. Here's the
code you used to build a scorecard:<br><code>books.values.each { |rate| ratings[rate] += 1 }</code>.</li>
</ul>
<p>On your computer, you probably have a lot of different files. Files with pictures in them,
files with programs in them. And files are often organized into folders, also called:
<strong>directories</strong>.</p>
<p>I've prepared a few directories for you. Take a look:
<code class="cmd">Dir.entries "/"</code></p>
<div class="answer">\["\.", .+\]</div>
</div>
<div class="stretcher">
<h3>The Private Collection of Dr. Dir</h3>
<p>You've just listed out everything in the top directory. The root directory, indicated
by a single slash. Containing some programs and other tutorials and such.</p>
<p>So, what is the <code>Dir.entries</code> method? Well, it's just a method, right?
<code>entries</code> is a method called on the <code>Dir</code> variable.
And <code>Dir</code> has a collection of methods for checking out file directories.</p>
<p>One other little thing we haven't really talked about openly. Method arguments, highlighted in green.</p>
<ul>
<li><code>Dir.entries <strong>"/"</strong></code>: Anything listed after a method
is considered an attachment.</li>
<li><code>print <strong>poem</strong></code>: See, <code>print</code> is an ordinary method. And the
poem is attached. To be printed.</li>
<li><code>print <strong>"pre", "event", "ual", "ism"</strong></code> has several arguments, with commas
between them.</li>
</ul>
<p>To list just the text files in that directory: <code class="cmd">Dir["/*.txt"]</code></p>
<div class="answer">\["\/comics\.txt"\]</div>
</div>
<div class="stretcher">
<h3>Come, Read Comics With Me</h3>
<p>The <code>Dir[]</code> method is like <code>entries</code> but you search for files
with wildcard characters. Here, we see those square brackets again! Notice how
they still mean, "I am looking for _____?"</p>
<p>More specifically: "I am looking for files which end with <code>.txt</code>."</p>
<p>Let's crack open this comics file, then. Here's the way:<br>
<code class="cmd">print File.read("/comics.txt")</code></p>
<div class="stdout">Achewood.+</div>
</div>
<div class="stretcher">
<h3>Mi Comicas, Tu Comicas</h3>
<p>All right! We can start to use files to store things. This is great because normally when
we exit Ruby, all our variables will be gone. Ruby, by itself, forgets these things.
But if we save things in files, we can read those files in future Ruby escapades.</p>
<p>Hey, and guess what? The <code>/Home</code> directory is yours! I gave it to you! I am generous! Let's make a copy of the comics file.</p>
<p>You'll want to: <code class="cmd">FileUtils.copy('/comics.txt', '/Home/comics.txt')</code>
</p><p><em>If you've already created the file, use File.delete('/Home/comics.txt') to trash it.</em></p>
<div class="answer">nil</div>
</div>
<div class="stretcher">
<h3>Your Own Turf</h3>
<p>Okay, you've got a copy. Check it: <code>Dir["/Home/*.txt"]</code></p>
<p>To add your own comic to the list, let's open the file in <strong>append</strong> mode.</p>
<p>Start like this: <code class="cmd">File.open("/Home/comics.txt", "a") do |f|</code>.</p>
<div class="stdout">..</div>
</div>
<div class="stretcher">
<h3>And Now For the Startling Conclusion</h3>
<p>So your prompt has <em>changed</em>. See that? Your prompt is a <strong>double</strong> dot now.</p>
<p>In this tutorial, this prompt means that Ruby is expecting you to type more.
As you type in the lines of Ruby code, the double dots will continue until you
are completely finished.</p>
<p>Hot tip: If you want to stop working on the code and break out of the double dots, use the <code>reset</code>
command. If you want to go the previous page of the tutorial, use the <code>back</code> command.</p>
<p>Here's your code. You've already typed the first line, so just enter the second line. (The <code>\n</code>
is an <em>Enter</em> character.</p>
<ul><li><code class="faded">File.open("/Home/comics.txt", "a") do |f|</code></li>
<li><code> f << "Cat and Girl: http://catandgirl.com/\n"</code></li>
<li><code class="faded">end</code></li>
</ul>
<p>And, since you're getting so advanced and capable here, one other tip: you can use the up and down arrow keys to
edit your old commands or run them again.</p>
<div class="stdout">..</div>
</div>
<div class="stretcher">
<h3>Ruby Sits Still</h3>
<p>That last line adds the <em>Cat and Girl</em> comic to the list, but Ruby's going to wait until you're totally finished to
take action.</p>
<p>Now, to finish the code you've started. You opened a new block when you typed <code>do</code>.
So far the blocks we've seen have used curly braces. This time we'll be using <code>do</code> and <code>end</code> instead
of curly braces. A lot of Rubyists will use <code>do...end</code> when the block goes on for many lines.</p>
<p>Let's get that block finished now, with: <code class="cmd">end</code></p>
<ul><li><code class="faded">File.open("/Home/comics.txt", "a") do |f|</code></li>
<li><code class="faded"> f << "Cat and Girl: http://catandgirl.com/\n"</code></li>
<li><code>end</code></li>
</ul>
<div class="answer">#.File:/Home/comics\.txt \(closed\).</div>
</div>
<div class="stretcher">
<h3>The Clock Nailed To the File</h3>
<p>Good, good! You've added that new comic to the file. You can see for yourself: <code>print File.read("/Home/comics.txt")</code></p>
<p>What time was it when you changed the file? Let's check. Type: <code class="cmd">File.mtime("/Home/comics.txt")</code></p>
<div class="answer">\d{4}-\d+-\d+ \d{2}:\d{2}:\d{2} [+-]\d{4}</div>
</div>
<div class="stretcher">
<h3>Just the Hour Hand</h3>
<p>Great, there's the time. The precise time exactly when you added to the file. The <code>mtime</code> gives you a Ruby Time object.</p>
<p>If you want to check just what hour it was, hit the up arrow key and change the line to: <code class="cmd">File.mtime("/Home/comics.txt").hour</code></p>
<div class="answer">\d+</div>
</div>
<div class="stretcher chapmark">
<h3>Hallo, Who's There? And Summary #5 Waves Its Hat!</h3>
<p>Well done, well done, well done, well done! Truly, truly, truly, truly, truuuuuuuuly!</p>
<p>Here's the last few minutes of your life in review:</p>
<ul>
<li><strong>Files.</strong> What more can be said? Lots of methods for editing files and lookin around in directories.</li>
<li><strong>Arguments.</strong> Arguments are a list of things sent into a method. With commas between. </li>
<li>We also spoke about <strong>do</strong> and <strong>end</strong> which are another way to make a block.</li>
</ul>
<p>You totally know how to use Ruby now. I mean you've got down the essentials. You just need to keep learning more methods and
try out more complex blocks.</p>
<p>But there's one side of Ruby we haven't settled. Making your own methods and classes.</p>
<p><em>Ahem!</em> Let's get it over with then.</p>
<p>Start with: <code class="cmd">def load_comics( path )</code></p>
<div class="stdout">..</div>
</div>
<div class="stretcher">
<h3>In Ruby, Def Leppard Means <em>Define Leppard (a Method)!</em></h3>
<p>Hey, okay, you done it. You're making your own method. You started with <code>def</code>, followed by the name of the method.
And a list of arguments which the method will need. This isn't too scary and dangerous!</p>
<p>All we have to do is fill it up with Ruby and finish it up with <code>end</code>.</p>
<p>Here's the code:</p>
<ul><li><code class="faded">def load_comics( path )</code></li>
<li><code> comics = {}</code></li>
<li><code> File.foreach(path) do |line|</code></li>
<li><code> name, url = line.split(': ')</code></li>
<li><code> comics[name] = url.strip</code></li>
<li><code> end</code></li>
<li><code> comics</code></li>
<li><code>end</code></li>
</ul>
<p>No need to indent, if you don't want. I just do that to make it read easier.</p>
<div class="answer">nil</div>
</div>
<div class="stretcher">
<h3>The Ripened Fruit of Your Own Creation</h3>
<p>A new method is born. Let us use it: <code class="cmd">comics = load_comics('/comics.txt')</code></p>
<p><em>If you have a problem, you might have mistyped. Use the <code>back</code> command and try again.</em></p>
<div class="answer">\{.*"Achewood"=."http://achewood.com/".*\}</div>
</div>
<div class="stretcher">
<h3>Hey, Cool, a Comics Thing</h3>
<p>In your Ruby window above, look at the code you've typed for the <code>load_comics</code> method. What is happening? You're
passing in the <code>path</code> variable and you're getting back the <code>comics</code> variable. Ruby lets the <code>comics</code>
hash trickle out the end of the method.</p>
<p>A number of methods were used to get the job done. See if you can spot them.</p>
<ul><li><strong>File.foreach</strong> is a method which opens a file and hands each line to the block. The <code>line</code>
variable inside the <code>do...end</code> block took turns with each line in the file.</li>
<li><strong>split</strong> is a method for strings, which breaks the string up into an array. An axe is laid on the colon
and the line is chopped in half, giving us the <code>url</code> and <code>name</code> for each comic.</li>
<li><strong>strip</strong> removes extra spaces around the name. Just in case.</li>
</ul>
<p>Right on. Bravo. You've got the comics in a Ruby hash. But what now? What good is this really?</p>
<p>Let's make a page of links. How about that? I went ahead and loaded a little library I've made for you.</p>
<p>Type: <code class="cmd">next</code>. This is temporary as I updates new lessons.</p>
<div class="answer">true</div>
</div>
<div class="stretcher">
<h3>Browser Puppetry</h3>
<p>Excellent, you've loaded the <em>popup</em> library. It's saved in a file in the <em>Libraries</em> folder. See: <code>Dir["/Libraries/*"]</code></p>
<p>The popup library contains a bunch of methods I've written which let you control a popup here on the Try Ruby site.</p>
<p>Here, try this: <code class="cmd">Popup.goto "http://google.com/"</code></p>
<div class="stdout">\033\[1;JSm.*popup_goto\(.*\)\033\[m.*</div>
</div>
<div class="stretcher">
<h3>Making Links and Spinning Webs</h3>
<p>Our own lovely, little popup to manipulate. You can also fill it with your own goodies. We'll start small:</p>
<ul><li><code>Popup.make {</code></li>
<li><code> h1 "My Links"</code></li>
<li><code> link "Go to Google", "http://google.com/"</code></li>
<li><code>}</code></li>
</ul>
<p>The term <code>h1</code> (<em>h-one</em>) means a level-one header. In HTML, this is the largest size of header.</p>
<div class="stdout">\033\[1;JSm.*popup_make\(.*h1.*a href.*\)\033\[m.*</div>
</div>
<div class="stretcher">
<h3>Popups Are So Easy, It's Crazy</h3>
<p>Looks good, you did it perfectly, just as you were asked. Let's make a list then.</p>
<p>Here's how you make a list with the popup library:</p>
<ul><li><code>Popup.make do</code></li>
<li><code> h1 "Things To Do"</code></li>
<li><code> list do</code></li>
<li><code> p "Try out Ruby"</code></li>
<li><code> p "Ride a tiger"</code></li>
<li><code> p "(down River Euphrates)"</code></li>
<li><code> end</code></li>
<li><code>end</code></li>
</ul>
<p>The <code>p</code> method is short for "paragraph".</p>
<div class="stdout">\033\[1;JSm.*popup_make\(.*h1.*ul.*li.*li.*\)\033\[m.*</div>
</div>
<div class="stretcher">
<h3>Spread the Comics on the Table</h3>
<p>Okay, this is coming along wonderfully. This is simple stuff, but keep in mind that you didn't know <em>any Ruby whatsoever</em> just fifteen minutes ago!</p>
<p>Last
step. Let's tie it all together, you know? Let's make it chime together
like a very nice set of glistening chimes on the beach in the
maginificent sunlight!</p>
<p>Make sure the comics are loaded: <code>comics = load_comics( '/comics.txt' )</code></p>
<p>Now, let's make a list of the links to each comic:</p>
<ul><li><code>Popup.make do</code></li>
<li><code> h1 "Comics on the Web"</code></li>
<li><code> list do</code></li>
<li><code> comics.each do |name, url|</code></li>
<li><code> link name, url</code></li>
<li><code> end</code></li>
<li><code> end</code></li>
<li><code>end</code></li>
</ul>
<p>You can click on the links and read the comics in the little window even! Smashing!</p>
<div class="stdout">\033\[1;JSm.*popup_make\(.*h1.*ul.*li.*a href.*li.*a href.*\)\033\[m.*</div>
</div>
<div class="stretcher chapmark">
<h3>Summary #6 Which Means You've Come So Far</h3>
<p>You're a level six Ruby cleric. I mean what a great job you've done. Let's review:</p>
<ul>
<li>You added your own method with <strong>def</strong> and you used that <code>load_comics</code> method several times.</li>
<li><strong>Libraries.</strong> You used the <code>require</code> method to load the popup library.<br>By typing: <code>require 'popup'</code></li>
<li>And if that wasn't enough, you made your own web page from a list of comics in a file. <strong>You made a real program!</strong></li>
</ul>
<p>So
what could possibly be next? What could you possibly have to learn now?
Ha, this is the best part. You've come such a long way that we're going
to uncover classes. For two more short lessons and you're done.</p>
<p>Earlier, we created a hash like this: <code class="cmd">Hash.new</code> Try it.</p>
<div class="answer">\{\}</div>
</div>
<div class="stretcher">
<h3>Not a School Class, a Working Class</h3>
<p>You see, the empty curly braces <code>{}</code> is a shortcut for <code>Hash.new</code>. The <code>new</code>
method is used to make objects of a certain class. (Think "class" as in
"working class" — a specific group of objects which are similar, have
the same jobs, the same shirts.)</p>
<p>Ask yourself this: <em>How would I make a blog in Ruby?</em>
Where would you start? Well, you might store your blog entries in a
file, right? But how would you keep track of the title of the entry and
the time it was posted? And when you loaded the file, how would it look
in Ruby? Would it be a Hash? Or an Array? Or an Array of Arrays? Or
something else? </p><p>I really think you'll want to use a class. You are already familiar with many classes: <code>Hash</code>, <code>Array</code>, <code>String</code>.</p>
<p>Let's make a new class: <code class="cmd">class BlogEntry</code>.</p>
<div class="stdout">..</div>
</div>
<div class="stretcher">
<h3>The Stuff Blogs are Made of</h3>
<p>You've opened up a new <code>BlogEntry</code> class. What is your blog entry made of? A title, sure. Also, a time when the entry was posted. The
full text of the entry.</p>
<p>We'll do a mood setting, too, just like LiveJournal. <img src="intro_files/sick.gif"> The Internet has really brought back stick people and smileys
out of bankruptcy. <em>Emote!</em></p>
<p>Okay, so you've got the first line of the class, here's the rest:</p>
<ul><li><code class="faded">class BlogEntry</code></li>
<li><code> attr_accessor :title, :time, :fulltext, :mood</code></li>
<li><code>end</code></li>
</ul>
<div class="answer">nil</div>
</div>
<div class="stretcher">
<h3>Accessors Are the Dangling Limbs</h3>
<p>Hey, good class, man. You've got a new <code>BlogEntry</code> class. To start an entry: <br><code class="cmd">entry = BlogEntry.new</code>.</p>
<p>In the class definition, you used a method called <code>attr_accessor</code>. There are many <strong>attr</strong>ibute methods like
this which add little settings to classes. These attributes are just variables attached to a class.</p>
<p>Think
of it this way. A class is like a person. That star-shaped human thing
out there. And the attributes are the dangling limbs, the different
parts that make up a body.</p>
<p>To set the title of your entry: <code class="cmd">entry.title = "Today Mt. Hood Was Stolen!"</code></p>
<div class="answer">".+"</div>
</div>
<div class="stretcher">
<h3>An Object, That Neat Little Package</h3>
<p>Go ahead and set the post time: <code class="cmd">entry.time = Time.now</code></p>
<p>And the mood: <code class="cmd">entry.mood = :sick</code></p>
<p>And the post itself: <code class="cmd">entry.fulltext = "I can't believe Mt. Hood was stolen! I am speechless! It was stolen by a giraffe who drove away
in his Cadillac Seville very nonchalant!!"</code></p>
<p>To see all your settings, just type at the prompt: <code class="cmd">entry</code>.</p>
<div class="answer">#.BlogEntry:0x[0-9a-f]+ ((@title|@mood|@time|@fulltext)=.*?, ){3}.*</div>
</div>
<div class="stretcher">
<h3>Quickening it Up</h3>
<p>Cool,
you're blog is awesome. Hey, let's make things a bit easier on you.
You're not going to want to set the time like that every time you post.
You just want to type in the title and the entry and the mood quickly,
right?</p>
<p>Let's add an <code>initialize</code> method.</p>
<ul><li><code>class BlogEntry</code></li>
<li><code> def initialize( title, mood, fulltext )</code></li>
<li><code> @time = Time.now</code></li>
<li><code> @title, @mood, @fulltext = title, mood, fulltext</code></li>
<li><code> end</code></li>
<li><code>end</code></li>
</ul>
<p>Once you've got that typed in, try making a new entry: <code class="cmd">BlogEntry.new</code></p>
<div class="stdout">ArgumentError: wrong number of arguments \(0 for 3\).*</div>
</div>
<div class="stretcher">
<h3>You've Taught Your Blog to Reject Worthless Things</h3>
<p>Did you see how inside the class we used the at-symbols? Like this: <code>@time = Time.now</code></p>
<p>Outside the class, we use accessors: <code>entry.time = Time.now</code> But inside we use <em>instance variables</em>: <code>@time = Time.now</code>
They're the exact same thing, but expressed in two different places of your program.</p>
<p>Your blog now needs a title, a mood and a post in order to work. When a new <code>BlogEntry</code> is created, the <code>initialize</code> method
is used to check for any arguments to <code>new</code>. Uh, we need three arguments!</p>
<p>Try it again with all three.</p><p>
</p><p><code class="cmd">entry2
= BlogEntry.new( "I Left my Hoodie on the Mountain!", :confused, "I am
never going back to that mountain and I hope a giraffe steals it." )</code></p>
<div class="answer">#.BlogEntry:0x[0-9a-f]+ ((@title|@mood|@time|@fulltext)=.*?, ){3}.*</div>
</div>
<div class="stretcher chapmark">
<h3>A Giraffe Has Not Stolen Summary #7</h3>
<p>Aha, you're here. And all in one piece. We're still going to make your blog real, but until then, let's review, okay?</p>
<ul>
<li><strong>Classes.</strong> Everything in Ruby is some kind of object. Classes explain objects. How a certain object works.
For example, you made a few blog entry objects and these objects are explained in the <code>BlogEntry</code> class.
In other words: you call them BlogEntry objects.</li>
<li><strong>Accessors</strong> are variables attached to an object which can be used <em>outside</em> the object. (<code>entry.time = Time.now</code>)</li>
<li><strong>Instance variables</strong> are the same variables you're using for accessors when <em>inside</em> the object.
Like in a method definition. (<code>@time = Time.now</code>)</li>
</ul>
<p>Okay,
let's wrap things up, kid. Here's the last chapter of the GRIPPING epic
story of Try Ruby! Now that you've got a taste of how it all works, how
are you going to use it around the house and in your grocer's freezer?
You're a great person (one of my favorites), but you need guidance.</p>
<p>Let's finish your blog. You have blog entries, but no actual blog.</p>
<p>Put the entries into an array: <code class="cmd">blog = [entry, entry2]</code></p>
<div class="answer">\[#.BlogEntry:0x[0-9a-f]+.*, #.BlogEntry:0x[0-9a-f]+.*\]</div>
</div>
<div class="stretcher">
<h3>It's All About Combining Things</h3>
<p>Some
beautiful things can be done with the simple parts of Ruby, especially
when you combine them together into new things. Here we've got a blog
made of an array of classes. And, actually, Ruby really does good with
this kind of creature.</p>
<p>Here's a few things you can do with your array blog:</p>
<ul><li>You'll want to sort your entries from newest to oldest. You can do this with:<br>
<code>blog.sort_by { |entry| entry.time }.reverse</code><br>See the <a href="http://ruby-doc.org/core/classes/Enumerable.html#method-i-sort_by" target="_new">sort_by</a> explanation for more.</li>
<li>If you want to search your blog for anything related to "cadillac": <br>
<code>blog.find_all { |entry| entry.fulltext.match(/cadillac/i) }</code><br>
Read all about <a href="http://ruby-doc.org/core-2.0/Enumerable.html#method-i-find_all" target="_new">find_all</a>
and <a href="http://ruby-doc.org/core-2.0/String.html#method-i-match" target="_new">match</a>
to figure out how that works. Also: the slashy <code>/giraffe/i</code> is a Regexp object, used for matching words.</li>
<li>Add new entries with <code>blog << new_entry</code><br>
And check out the <a href="http://ruby-doc.org/core-2.0/Array.html#method-i-3C-3C" target="_new"><<</a> method documentation.</li>
</ul>
<p>You can browse a list of all Ruby's built-in methods at <a href="http://ruby-doc.org/core/" target="_new">ruby-doc.org's core</a> list.
Another good list is at the <a href="http://www.whytheluckystiff.net/ruby/pickaxe/html/builtins.html">online pickaxe</a>.</p>
<p>One <em>really</em> useful method (I probably use this more than anything else) is <code>map</code>. Type: <code class="cmd">blog.map { |entry| entry.mood }</code></p>
<div class="answer">\[(:\w+, )+:\w+\]</div>
</div>
<div class="stretcher">
<h3>Look at His Face — The Transformation Has Begun</h3>
<p>The <code>map</code> method cycles through an array and replaces each item with something new. Say you wanted to replace each of your blog entries
with the name <em>Bruce Willis</em>. Do it so: <code>blog.map { "Bruce Willis" }</code></p>
<p>Since the block always returns the string "Bruce Willis", that's what you get. In the code you just used, the <code>entry</code> was swapped out
for only the <code>entry.mood</code>.</p>
<p>Now,
I want you to make a popup with your blog entries. I'm not going to
give you all of the code. I'm just going to give you part of it.</p>
<ul><li><code>blog.each do |entry|</code></li>
<li><code> h2 entry.title</code></li>
<li><code> p entry.fulltext</code></li>
<li><code>end</code></li>
</ul>
<p>Now, I expect you to put the popup code around it and add an <code>h1</code> title with the name of your blog. For extra haroompf, have the time of each entry display.</p>
<div class="stdout">\033\[1;JSm.*popup_make\(.*h1.*h2.*li.*h2.*li.*\)\033\[m.*</div>
</div>
<div class="stretcher">
<h3>You are Some Kind of Web Guru, I Have Stars in My Eyes</h3>
<p>Good,
that's it! This is exactly the code you can use to write your own real
Ruby blog. If you're feeling adventurous, I'd check out the Rails <a href="http://rubyonrails.org/screencasts" target="_new">videos</a> which show a swift young fellow creating a blog in 15 minutes. You just sit back and watch.</p>
<p>I
should mention Rails. You have been learning the Ruby language, how to
speak it. But Rails is a bunch of libraries (sort of like the popup
library we've been using.) It's a very powerful toolkit for building
websites. If you're interested in learning about Rails, I would <a href="http://rubyonrails.org/" target="_new">head
over there</a> right away. Start using your Ruby skills proper!</p>
<p>One thing Rails has is easy methods for dates. Like, try: <code class="cmd">Time.now - 2.weeks</code></p>
<div class="load">class Integer; def weeks; self * 7*24*60*60; end; end</div>
<div class="answer">\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-+]\d{4}</div>
</div>
<div class="stretcher">
<h3>If You Want to Start Small</h3>
<p>If you'd like to start writing little Ruby programs just to practice, I have a project called <a href="http://code.whytheluckystiff.net/mouseHole/" target="_new">MouseHole</a>
which is a little web toolkit for writing short Ruby programs. You can look over a <a href="http://code.whytheluckystiff.net/mouseHole/wiki/UserScripts" target="_new">few
scripts</a> to see what I mean.</p>
<p>MouseHole
isn't for writing web sites really. It's just for writing little
programs you run inside your browser. Like there's a notepad program
for MouseHole and a program which adds a mouse picture next to links on
the web which link to MouseHole programs.</p>
<p>I've got a MouseHole script inside a file here:<br>
<code class="cmd">print File.read("/MouseHole/flickrpedia.user.rb")</code></p>
<div class="stdout">.*Inserts Wikipedia links for Flickr tags.*</div>
</div>
<div class="stretcher chapmark">
<h3>Summary #8, The Hey-Relax-You-Did-Good Summary</h3>
<p>This last section took a moment to wind down, to give you some pointers as to how you can use Ruby. If you enjoyed yourself,
download Ruby and install it.</p>
<ul><li>For Mac: <a href="http://homepage.mac.com/discord/Ruby/" target="_new">Ruby OS X Installer Package</a></li>
<li>For Windows: <a href="http://rubyforge.org/frs/download.php/4174/ruby182-15.exe" target="_new">Ruby Installer for Windows</a></li>
<li>Other platforms: <a href="http://www.ruby-lang.org/en/20020102.html" target="_new">Source</a></li></ul>
<p>Once you have Ruby installed, you can use Interactive Ruby by running <code>irb</code> on your system's prompt. For more on Irb,
there's <a href="http://poignantguide.net/ruby/expansion-pak-1.html" target="_new">The Tiger's Vest</a> to help you.</p>
<p>You
really deserve a double-layer cake with double-double frosting and a
guy playing one of those guitars that's a double guitar. I mean you
finished, you really did! No doubt about it, you're a certified
red-blooded smartiac!</p>
<br>
</div>
</body>
</html>