y_nelson 2.0.6 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +675 -22
- data/README.md +3 -3
- data/Ruby_for_YNelson_Users_in_20_minutes.lyx +2254 -0
- data/Ruby_for_YNelson_Users_in_20_minutes.pdf +0 -0
- data/YNelson_FPN_&_ZZ_domain_model_hands_on_in_color.pdf +0 -0
- data/YPetri_FPN_domain_model_hands_on_in_color.lyx +2766 -0
- data/lib/y_nelson/dsl.rb +1 -1
- data/lib/y_nelson/version.rb +1 -1
- data/lib/y_nelson.rb +2 -0
- data/test/y_nelson_test.rb +1 -3
- data/y_nelson.gemspec +1 -1
- metadata +7 -4
- data/zz.png +0 -0
@@ -0,0 +1,2254 @@
|
|
1
|
+
#LyX 2.0 created this file. For more info see http://www.lyx.org/
|
2
|
+
\lyxformat 413
|
3
|
+
\begin_document
|
4
|
+
\begin_header
|
5
|
+
\textclass article
|
6
|
+
\use_default_options false
|
7
|
+
\maintain_unincluded_children false
|
8
|
+
\language english
|
9
|
+
\language_package default
|
10
|
+
\inputencoding auto
|
11
|
+
\fontencoding global
|
12
|
+
\font_roman default
|
13
|
+
\font_sans default
|
14
|
+
\font_typewriter default
|
15
|
+
\font_default_family default
|
16
|
+
\use_non_tex_fonts false
|
17
|
+
\font_sc false
|
18
|
+
\font_osf false
|
19
|
+
\font_sf_scale 100
|
20
|
+
\font_tt_scale 100
|
21
|
+
|
22
|
+
\graphics default
|
23
|
+
\default_output_format default
|
24
|
+
\output_sync 0
|
25
|
+
\bibtex_command default
|
26
|
+
\index_command default
|
27
|
+
\paperfontsize default
|
28
|
+
\spacing single
|
29
|
+
\use_hyperref false
|
30
|
+
\papersize default
|
31
|
+
\use_geometry true
|
32
|
+
\use_amsmath 1
|
33
|
+
\use_esint 1
|
34
|
+
\use_mhchem 1
|
35
|
+
\use_mathdots 1
|
36
|
+
\cite_engine natbib_authoryear
|
37
|
+
\use_bibtopic false
|
38
|
+
\use_indices false
|
39
|
+
\paperorientation portrait
|
40
|
+
\suppress_date false
|
41
|
+
\use_refstyle 0
|
42
|
+
\index Index
|
43
|
+
\shortcut idx
|
44
|
+
\color #008000
|
45
|
+
\end_index
|
46
|
+
\leftmargin 2.2cm
|
47
|
+
\topmargin 3cm
|
48
|
+
\rightmargin 2.2cm
|
49
|
+
\bottommargin 3cm
|
50
|
+
\secnumdepth 3
|
51
|
+
\tocdepth 3
|
52
|
+
\paragraph_separation indent
|
53
|
+
\paragraph_indentation default
|
54
|
+
\quotes_language english
|
55
|
+
\papercolumns 1
|
56
|
+
\papersides 1
|
57
|
+
\paperpagestyle default
|
58
|
+
\tracking_changes false
|
59
|
+
\output_changes false
|
60
|
+
\html_math_output 0
|
61
|
+
\html_css_as_file 0
|
62
|
+
\html_be_strict false
|
63
|
+
\end_header
|
64
|
+
|
65
|
+
\begin_body
|
66
|
+
|
67
|
+
\begin_layout Title
|
68
|
+
Ruby for YNelson Users in 20 minutes
|
69
|
+
\end_layout
|
70
|
+
|
71
|
+
\begin_layout Standard
|
72
|
+
For
|
73
|
+
\family typewriter
|
74
|
+
YNelson
|
75
|
+
\family default
|
76
|
+
users, basic Ruby syntax is necessary.
|
77
|
+
This document provides the Ruby syntax primer for
|
78
|
+
\family typewriter
|
79
|
+
YNelson
|
80
|
+
\family default
|
81
|
+
users.
|
82
|
+
|
83
|
+
\series bold
|
84
|
+
This document is better done in one session, as the provided code samples
|
85
|
+
rely on each other.
|
86
|
+
|
87
|
+
\series default
|
88
|
+
If you are familiar with Ruby, you do not need to read this document at
|
89
|
+
all.
|
90
|
+
Those who want more thorough introduction to the language, I recommend
|
91
|
+
http://www.rubyist.net/~slagell/ruby/index.html, or any of the many Ruby textbooks.
|
92
|
+
\end_layout
|
93
|
+
|
94
|
+
\begin_layout Subsection*
|
95
|
+
Variables and Constants
|
96
|
+
\end_layout
|
97
|
+
|
98
|
+
\begin_layout Standard
|
99
|
+
In Ruby, everything is an
|
100
|
+
\emph on
|
101
|
+
\color red
|
102
|
+
object
|
103
|
+
\emph default
|
104
|
+
\color inherit
|
105
|
+
.
|
106
|
+
Objects can be assigned to
|
107
|
+
\emph on
|
108
|
+
\color red
|
109
|
+
variables
|
110
|
+
\emph default
|
111
|
+
\color inherit
|
112
|
+
or
|
113
|
+
\emph on
|
114
|
+
\color red
|
115
|
+
constants
|
116
|
+
\emph default
|
117
|
+
\color inherit
|
118
|
+
.
|
119
|
+
Ruby constants
|
120
|
+
\color red
|
121
|
+
must always start with capital letter
|
122
|
+
\color inherit
|
123
|
+
.
|
124
|
+
Variables starting with small letter are
|
125
|
+
\emph on
|
126
|
+
\color red
|
127
|
+
local variables
|
128
|
+
\emph default
|
129
|
+
\color inherit
|
130
|
+
.
|
131
|
+
(Other types of variables are
|
132
|
+
\emph on
|
133
|
+
\color red
|
134
|
+
instance variables
|
135
|
+
\emph default
|
136
|
+
\color inherit
|
137
|
+
,
|
138
|
+
\emph on
|
139
|
+
\color red
|
140
|
+
class variables
|
141
|
+
\emph default
|
142
|
+
\color inherit
|
143
|
+
and
|
144
|
+
\emph on
|
145
|
+
\color red
|
146
|
+
global constants
|
147
|
+
\emph default
|
148
|
+
\color inherit
|
149
|
+
; this is not important at the moment.)
|
150
|
+
\end_layout
|
151
|
+
|
152
|
+
\begin_layout LyX-Code
|
153
|
+
alpha = 1
|
154
|
+
\end_layout
|
155
|
+
|
156
|
+
\begin_layout LyX-Code
|
157
|
+
#=> 1
|
158
|
+
\end_layout
|
159
|
+
|
160
|
+
\begin_layout LyX-Code
|
161
|
+
beta = [1, 2]
|
162
|
+
\end_layout
|
163
|
+
|
164
|
+
\begin_layout LyX-Code
|
165
|
+
#=> [1, 2]
|
166
|
+
\end_layout
|
167
|
+
|
168
|
+
\begin_layout LyX-Code
|
169
|
+
Gamma = { x: 1, y: 2, z: 3 }
|
170
|
+
\end_layout
|
171
|
+
|
172
|
+
\begin_layout LyX-Code
|
173
|
+
#=> {:x=>1, :y=>2, :z=>3}
|
174
|
+
\end_layout
|
175
|
+
|
176
|
+
\begin_layout Standard
|
177
|
+
You can check this using
|
178
|
+
\family typewriter
|
179
|
+
\color red
|
180
|
+
defined?
|
181
|
+
\family default
|
182
|
+
\color inherit
|
183
|
+
operator:
|
184
|
+
\end_layout
|
185
|
+
|
186
|
+
\begin_layout LyX-Code
|
187
|
+
defined? alpha
|
188
|
+
\end_layout
|
189
|
+
|
190
|
+
\begin_layout LyX-Code
|
191
|
+
#=> "local-variable"
|
192
|
+
\end_layout
|
193
|
+
|
194
|
+
\begin_layout LyX-Code
|
195
|
+
defined? Gamma
|
196
|
+
\end_layout
|
197
|
+
|
198
|
+
\begin_layout LyX-Code
|
199
|
+
#=> "constant"
|
200
|
+
\end_layout
|
201
|
+
|
202
|
+
\begin_layout Subsection*
|
203
|
+
Methods
|
204
|
+
\end_layout
|
205
|
+
|
206
|
+
\begin_layout Standard
|
207
|
+
Different classes respond to different
|
208
|
+
\emph on
|
209
|
+
\color red
|
210
|
+
methods
|
211
|
+
\emph default
|
212
|
+
\color inherit
|
213
|
+
, and respond to them differently:
|
214
|
+
\end_layout
|
215
|
+
|
216
|
+
\begin_layout LyX-Code
|
217
|
+
beta.
|
218
|
+
\color red
|
219
|
+
size
|
220
|
+
\end_layout
|
221
|
+
|
222
|
+
\begin_layout LyX-Code
|
223
|
+
#=> 2
|
224
|
+
\end_layout
|
225
|
+
|
226
|
+
\begin_layout LyX-Code
|
227
|
+
Gamma.size
|
228
|
+
\end_layout
|
229
|
+
|
230
|
+
\begin_layout LyX-Code
|
231
|
+
#=> 3
|
232
|
+
\end_layout
|
233
|
+
|
234
|
+
\begin_layout LyX-Code
|
235
|
+
Gamma.
|
236
|
+
\color red
|
237
|
+
keys
|
238
|
+
\end_layout
|
239
|
+
|
240
|
+
\begin_layout LyX-Code
|
241
|
+
#=> [:x, :y, :z]
|
242
|
+
\end_layout
|
243
|
+
|
244
|
+
\begin_layout LyX-Code
|
245
|
+
Gamma.
|
246
|
+
\color red
|
247
|
+
values
|
248
|
+
\end_layout
|
249
|
+
|
250
|
+
\begin_layout LyX-Code
|
251
|
+
#=> [1, 2, 3]
|
252
|
+
\end_layout
|
253
|
+
|
254
|
+
\begin_layout LyX-Code
|
255
|
+
beta.keys
|
256
|
+
\end_layout
|
257
|
+
|
258
|
+
\begin_layout LyX-Code
|
259
|
+
#=> NoMethodError: undefined method `keys' for [1, 2]:Array
|
260
|
+
\end_layout
|
261
|
+
|
262
|
+
\begin_layout Standard
|
263
|
+
Methods can be defined by
|
264
|
+
\family typewriter
|
265
|
+
\color red
|
266
|
+
def
|
267
|
+
\family default
|
268
|
+
\color inherit
|
269
|
+
keyword:
|
270
|
+
\end_layout
|
271
|
+
|
272
|
+
\begin_layout LyX-Code
|
273
|
+
|
274
|
+
\color red
|
275
|
+
def
|
276
|
+
\color inherit
|
277
|
+
average( a, b )
|
278
|
+
\end_layout
|
279
|
+
|
280
|
+
\begin_layout LyX-Code
|
281
|
+
( a + b ).
|
282
|
+
\color red
|
283
|
+
to_f
|
284
|
+
\color inherit
|
285
|
+
/ 2
|
286
|
+
\end_layout
|
287
|
+
|
288
|
+
\begin_layout LyX-Code
|
289
|
+
|
290
|
+
\color red
|
291
|
+
end
|
292
|
+
\end_layout
|
293
|
+
|
294
|
+
\begin_layout LyX-Code
|
295
|
+
#=> nil
|
296
|
+
\end_layout
|
297
|
+
|
298
|
+
\begin_layout LyX-Code
|
299
|
+
average( 2, 3 )
|
300
|
+
\end_layout
|
301
|
+
|
302
|
+
\begin_layout LyX-Code
|
303
|
+
#=> 2.5
|
304
|
+
\end_layout
|
305
|
+
|
306
|
+
\begin_layout Standard
|
307
|
+
In the code example above, '
|
308
|
+
\family typewriter
|
309
|
+
to_f
|
310
|
+
\family default
|
311
|
+
' method performs conversion of an integer into a floating point number,
|
312
|
+
which is not important.
|
313
|
+
\end_layout
|
314
|
+
|
315
|
+
\begin_layout Subsection*
|
316
|
+
Classes
|
317
|
+
\end_layout
|
318
|
+
|
319
|
+
\begin_layout Standard
|
320
|
+
Every object belongs to some
|
321
|
+
\emph on
|
322
|
+
\color red
|
323
|
+
class
|
324
|
+
\emph default
|
325
|
+
\color inherit
|
326
|
+
(object type):
|
327
|
+
\end_layout
|
328
|
+
|
329
|
+
\begin_layout LyX-Code
|
330
|
+
alpha.
|
331
|
+
\color red
|
332
|
+
class
|
333
|
+
\end_layout
|
334
|
+
|
335
|
+
\begin_layout LyX-Code
|
336
|
+
#=>
|
337
|
+
\color red
|
338
|
+
Fixnum
|
339
|
+
\end_layout
|
340
|
+
|
341
|
+
\begin_layout LyX-Code
|
342
|
+
beta.class
|
343
|
+
\end_layout
|
344
|
+
|
345
|
+
\begin_layout LyX-Code
|
346
|
+
#=>
|
347
|
+
\color red
|
348
|
+
Array
|
349
|
+
\end_layout
|
350
|
+
|
351
|
+
\begin_layout LyX-Code
|
352
|
+
Gamma.class
|
353
|
+
\end_layout
|
354
|
+
|
355
|
+
\begin_layout LyX-Code
|
356
|
+
#=>
|
357
|
+
\color red
|
358
|
+
Hash
|
359
|
+
\end_layout
|
360
|
+
|
361
|
+
\begin_layout Standard
|
362
|
+
New classes can be defined with
|
363
|
+
\family typewriter
|
364
|
+
\color red
|
365
|
+
class
|
366
|
+
\family default
|
367
|
+
\color inherit
|
368
|
+
keyword.
|
369
|
+
The methods defined inside the class will become the
|
370
|
+
\emph on
|
371
|
+
\color red
|
372
|
+
instance methods
|
373
|
+
\emph default
|
374
|
+
\color inherit
|
375
|
+
of that class:
|
376
|
+
\end_layout
|
377
|
+
|
378
|
+
\begin_layout LyX-Code
|
379
|
+
class Dog
|
380
|
+
\end_layout
|
381
|
+
|
382
|
+
\begin_layout LyX-Code
|
383
|
+
def speak!
|
384
|
+
\end_layout
|
385
|
+
|
386
|
+
\begin_layout LyX-Code
|
387
|
+
|
388
|
+
\color red
|
389
|
+
puts
|
390
|
+
\color inherit
|
391
|
+
"Bow wow!"
|
392
|
+
\end_layout
|
393
|
+
|
394
|
+
\begin_layout LyX-Code
|
395
|
+
end
|
396
|
+
\end_layout
|
397
|
+
|
398
|
+
\begin_layout LyX-Code
|
399
|
+
end
|
400
|
+
\end_layout
|
401
|
+
|
402
|
+
\begin_layout LyX-Code
|
403
|
+
#=> nil
|
404
|
+
\end_layout
|
405
|
+
|
406
|
+
\begin_layout LyX-Code
|
407
|
+
Pochi = Dog.
|
408
|
+
\color red
|
409
|
+
new
|
410
|
+
\end_layout
|
411
|
+
|
412
|
+
\begin_layout LyX-Code
|
413
|
+
#=> #<Dog:0x9c214ac>
|
414
|
+
\end_layout
|
415
|
+
|
416
|
+
\begin_layout LyX-Code
|
417
|
+
Pochi.speak!
|
418
|
+
\end_layout
|
419
|
+
|
420
|
+
\begin_layout LyX-Code
|
421
|
+
#=> Bow wow!
|
422
|
+
\end_layout
|
423
|
+
|
424
|
+
\begin_layout LyX-Code
|
425
|
+
class Cat
|
426
|
+
\end_layout
|
427
|
+
|
428
|
+
\begin_layout LyX-Code
|
429
|
+
def speak!
|
430
|
+
\end_layout
|
431
|
+
|
432
|
+
\begin_layout LyX-Code
|
433
|
+
puts "Meow"
|
434
|
+
\end_layout
|
435
|
+
|
436
|
+
\begin_layout LyX-Code
|
437
|
+
end
|
438
|
+
\end_layout
|
439
|
+
|
440
|
+
\begin_layout LyX-Code
|
441
|
+
end
|
442
|
+
\end_layout
|
443
|
+
|
444
|
+
\begin_layout LyX-Code
|
445
|
+
#=> nil
|
446
|
+
\end_layout
|
447
|
+
|
448
|
+
\begin_layout LyX-Code
|
449
|
+
Tama = Cat.new
|
450
|
+
\end_layout
|
451
|
+
|
452
|
+
\begin_layout LyX-Code
|
453
|
+
#=> #<Cat:0x98efb80>
|
454
|
+
\end_layout
|
455
|
+
|
456
|
+
\begin_layout LyX-Code
|
457
|
+
Tama.speak!
|
458
|
+
\end_layout
|
459
|
+
|
460
|
+
\begin_layout LyX-Code
|
461
|
+
#=> Meow
|
462
|
+
\end_layout
|
463
|
+
|
464
|
+
\begin_layout Standard
|
465
|
+
These two classes now represent respectively dogs and cats in your irb session.
|
466
|
+
In the code above, you could notice '
|
467
|
+
\family typewriter
|
468
|
+
new
|
469
|
+
\family default
|
470
|
+
' method, used to create instances from the defined classes, and '
|
471
|
+
\family typewriter
|
472
|
+
puts
|
473
|
+
\family default
|
474
|
+
' method, used to simply print characters on the screen.
|
475
|
+
\end_layout
|
476
|
+
|
477
|
+
\begin_layout Subsection*
|
478
|
+
Strings, Symbols, Arrays and Hashes
|
479
|
+
\end_layout
|
480
|
+
|
481
|
+
\begin_layout Standard
|
482
|
+
For
|
483
|
+
\family typewriter
|
484
|
+
YPetri
|
485
|
+
\family default
|
486
|
+
users, it will be especially necessary to learn more about
|
487
|
+
\emph on
|
488
|
+
\color red
|
489
|
+
strings
|
490
|
+
\emph default
|
491
|
+
\color inherit
|
492
|
+
,
|
493
|
+
\emph on
|
494
|
+
\color red
|
495
|
+
symbols
|
496
|
+
\emph default
|
497
|
+
\color inherit
|
498
|
+
,
|
499
|
+
\emph on
|
500
|
+
\color red
|
501
|
+
arrays
|
502
|
+
\emph default
|
503
|
+
\color inherit
|
504
|
+
,
|
505
|
+
\emph on
|
506
|
+
\color red
|
507
|
+
hashes
|
508
|
+
\emph default
|
509
|
+
\color inherit
|
510
|
+
, and how to define and read
|
511
|
+
\emph on
|
512
|
+
\color red
|
513
|
+
closures
|
514
|
+
\emph default
|
515
|
+
\color inherit
|
516
|
+
(aka.
|
517
|
+
|
518
|
+
\emph on
|
519
|
+
anonymous functions
|
520
|
+
\emph default
|
521
|
+
).
|
522
|
+
Strings and symbols are among the most basic Ruby objects, while arrays
|
523
|
+
and hashes are important in understanding
|
524
|
+
\emph on
|
525
|
+
\color red
|
526
|
+
argument passing
|
527
|
+
\emph default
|
528
|
+
\color inherit
|
529
|
+
to methods and closures.
|
530
|
+
|
531
|
+
\series bold
|
532
|
+
\color blue
|
533
|
+
Understanding argument passing and closure writing is essential in using
|
534
|
+
YPetri DSL.
|
535
|
+
\end_layout
|
536
|
+
|
537
|
+
\begin_layout Subsubsection*
|
538
|
+
Strings
|
539
|
+
\end_layout
|
540
|
+
|
541
|
+
\begin_layout Standard
|
542
|
+
A string is simply a sequence of characters, which can be defined using
|
543
|
+
single or double quotes (
|
544
|
+
\family typewriter
|
545
|
+
\color red
|
546
|
+
'
|
547
|
+
\family default
|
548
|
+
\color inherit
|
549
|
+
or
|
550
|
+
\family typewriter
|
551
|
+
\color red
|
552
|
+
"
|
553
|
+
\family default
|
554
|
+
\color inherit
|
555
|
+
):
|
556
|
+
\end_layout
|
557
|
+
|
558
|
+
\begin_layout LyX-Code
|
559
|
+
my_string = 'Hello world!'
|
560
|
+
\end_layout
|
561
|
+
|
562
|
+
\begin_layout LyX-Code
|
563
|
+
#=> "Hello world!"
|
564
|
+
\end_layout
|
565
|
+
|
566
|
+
\begin_layout LyX-Code
|
567
|
+
my_string.class
|
568
|
+
\end_layout
|
569
|
+
|
570
|
+
\begin_layout LyX-Code
|
571
|
+
#=>
|
572
|
+
\color red
|
573
|
+
String
|
574
|
+
\end_layout
|
575
|
+
|
576
|
+
\begin_layout Standard
|
577
|
+
Strings are mutable (can be changed):
|
578
|
+
\end_layout
|
579
|
+
|
580
|
+
\begin_layout LyX-Code
|
581
|
+
my_string.
|
582
|
+
\color red
|
583
|
+
object_id
|
584
|
+
\end_layout
|
585
|
+
|
586
|
+
\begin_layout LyX-Code
|
587
|
+
#=> 81571950
|
588
|
+
\end_layout
|
589
|
+
|
590
|
+
\begin_layout LyX-Code
|
591
|
+
7.
|
592
|
+
\color red
|
593
|
+
times
|
594
|
+
\color inherit
|
595
|
+
|
596
|
+
\color red
|
597
|
+
do
|
598
|
+
\color inherit
|
599
|
+
my_string.
|
600
|
+
\color red
|
601
|
+
chop!
|
602
|
+
\color inherit
|
603
|
+
|
604
|
+
\color red
|
605
|
+
end
|
606
|
+
\end_layout
|
607
|
+
|
608
|
+
\begin_layout LyX-Code
|
609
|
+
#=> 7
|
610
|
+
\end_layout
|
611
|
+
|
612
|
+
\begin_layout LyX-Code
|
613
|
+
my_string
|
614
|
+
\end_layout
|
615
|
+
|
616
|
+
\begin_layout LyX-Code
|
617
|
+
#=> "Hello"
|
618
|
+
\end_layout
|
619
|
+
|
620
|
+
\begin_layout LyX-Code
|
621
|
+
my_string.object_id
|
622
|
+
\end_layout
|
623
|
+
|
624
|
+
\begin_layout LyX-Code
|
625
|
+
#=> 81571950
|
626
|
+
\end_layout
|
627
|
+
|
628
|
+
\begin_layout Standard
|
629
|
+
Above, you can newly notice
|
630
|
+
\family typewriter
|
631
|
+
times
|
632
|
+
\family default
|
633
|
+
method,
|
634
|
+
\family typewriter
|
635
|
+
do ...
|
636
|
+
end
|
637
|
+
\family default
|
638
|
+
block, and
|
639
|
+
\family typewriter
|
640
|
+
chop!
|
641
|
+
\family default
|
642
|
+
method that removes the last character from
|
643
|
+
\family typewriter
|
644
|
+
my_string
|
645
|
+
\family default
|
646
|
+
7 times, until only
|
647
|
+
\family typewriter
|
648
|
+
"Hello"
|
649
|
+
\family default
|
650
|
+
remains.
|
651
|
+
But the important thing is that as
|
652
|
+
\family typewriter
|
653
|
+
object_id
|
654
|
+
\family default
|
655
|
+
method shows,
|
656
|
+
\family typewriter
|
657
|
+
my_string
|
658
|
+
\family default
|
659
|
+
is still the same object (same
|
660
|
+
\emph on
|
661
|
+
\color red
|
662
|
+
object id
|
663
|
+
\emph default
|
664
|
+
\color inherit
|
665
|
+
), although the contents is changed.
|
666
|
+
\end_layout
|
667
|
+
|
668
|
+
\begin_layout LyX-Code
|
669
|
+
my_string
|
670
|
+
\color red
|
671
|
+
<<
|
672
|
+
\color inherit
|
673
|
+
"Pochi!"
|
674
|
+
\end_layout
|
675
|
+
|
676
|
+
\begin_layout LyX-Code
|
677
|
+
#=> "Hello Pochi!"
|
678
|
+
\end_layout
|
679
|
+
|
680
|
+
\begin_layout LyX-Code
|
681
|
+
my_string.object_id
|
682
|
+
\end_layout
|
683
|
+
|
684
|
+
\begin_layout LyX-Code
|
685
|
+
#=> 81571950
|
686
|
+
\end_layout
|
687
|
+
|
688
|
+
\begin_layout Standard
|
689
|
+
Again,
|
690
|
+
\family typewriter
|
691
|
+
<<
|
692
|
+
\family default
|
693
|
+
operator changed the contents, but the object id remained the same.
|
694
|
+
\end_layout
|
695
|
+
|
696
|
+
\begin_layout Subsubsection*
|
697
|
+
Symbols
|
698
|
+
\end_layout
|
699
|
+
|
700
|
+
\begin_layout Standard
|
701
|
+
Unlike strings, symbols are immutable – they never change.
|
702
|
+
They are written with colon (
|
703
|
+
\family typewriter
|
704
|
+
\color red
|
705
|
+
:
|
706
|
+
\family default
|
707
|
+
\color inherit
|
708
|
+
):
|
709
|
+
\end_layout
|
710
|
+
|
711
|
+
\begin_layout LyX-Code
|
712
|
+
:Pochi.class
|
713
|
+
\end_layout
|
714
|
+
|
715
|
+
\begin_layout LyX-Code
|
716
|
+
#=>
|
717
|
+
\color red
|
718
|
+
Symbol
|
719
|
+
\end_layout
|
720
|
+
|
721
|
+
\begin_layout Subsubsection*
|
722
|
+
Arrays
|
723
|
+
\end_layout
|
724
|
+
|
725
|
+
\begin_layout Standard
|
726
|
+
As seen earlier, they can be defined with square brackets
|
727
|
+
\family typewriter
|
728
|
+
[]
|
729
|
+
\family default
|
730
|
+
.
|
731
|
+
Square brackets are also used to address the array elements, counting from
|
732
|
+
0.
|
733
|
+
\end_layout
|
734
|
+
|
735
|
+
\begin_layout LyX-Code
|
736
|
+
my_array = [ Pochi, Tama ]
|
737
|
+
\end_layout
|
738
|
+
|
739
|
+
\begin_layout LyX-Code
|
740
|
+
#=> [#<Dog:0x9c214ac>, #<Cat:0x98efb80>]
|
741
|
+
\end_layout
|
742
|
+
|
743
|
+
\begin_layout LyX-Code
|
744
|
+
my_array[0]
|
745
|
+
\end_layout
|
746
|
+
|
747
|
+
\begin_layout LyX-Code
|
748
|
+
#=> #<Dog:0x9c214ac>
|
749
|
+
\end_layout
|
750
|
+
|
751
|
+
\begin_layout Standard
|
752
|
+
Negative numbers can be used to address the elements from the end of the
|
753
|
+
array:
|
754
|
+
\end_layout
|
755
|
+
|
756
|
+
\begin_layout LyX-Code
|
757
|
+
my_array[-1]
|
758
|
+
\end_layout
|
759
|
+
|
760
|
+
\begin_layout LyX-Code
|
761
|
+
#=> #<Cat:0x98efb80>
|
762
|
+
\end_layout
|
763
|
+
|
764
|
+
\begin_layout LyX-Code
|
765
|
+
my_array[-2]
|
766
|
+
\end_layout
|
767
|
+
|
768
|
+
\begin_layout LyX-Code
|
769
|
+
#=> #<Dog:0x9c214ac>
|
770
|
+
\end_layout
|
771
|
+
|
772
|
+
\begin_layout Subsubsection*
|
773
|
+
Hashes
|
774
|
+
\end_layout
|
775
|
+
|
776
|
+
\begin_layout Standard
|
777
|
+
As for hashes, there are two ways of defining them.
|
778
|
+
The first way uses
|
779
|
+
\emph on
|
780
|
+
\color red
|
781
|
+
Ruby rocket
|
782
|
+
\emph default
|
783
|
+
\color inherit
|
784
|
+
(
|
785
|
+
\family typewriter
|
786
|
+
\color red
|
787
|
+
=>
|
788
|
+
\family default
|
789
|
+
\color inherit
|
790
|
+
):
|
791
|
+
\end_layout
|
792
|
+
|
793
|
+
\begin_layout LyX-Code
|
794
|
+
h1 = { Pochi => "dog", Tama => "cat" }
|
795
|
+
\end_layout
|
796
|
+
|
797
|
+
\begin_layout LyX-Code
|
798
|
+
#=> {#<Dog:0x9c214ac>=>"dog", #<Cat:0x98efb80>=>"cat"}
|
799
|
+
\end_layout
|
800
|
+
|
801
|
+
\begin_layout LyX-Code
|
802
|
+
h1[ Tama ]
|
803
|
+
\end_layout
|
804
|
+
|
805
|
+
\begin_layout LyX-Code
|
806
|
+
#=> "cat"
|
807
|
+
\end_layout
|
808
|
+
|
809
|
+
\begin_layout LyX-Code
|
810
|
+
h1[ Pochi ]
|
811
|
+
\end_layout
|
812
|
+
|
813
|
+
\begin_layout LyX-Code
|
814
|
+
#=> "dog"
|
815
|
+
\end_layout
|
816
|
+
|
817
|
+
\begin_layout Standard
|
818
|
+
The second way is possible only when the keys are symbols.
|
819
|
+
It is done by shifting the colon to the right side of the symbol:
|
820
|
+
\end_layout
|
821
|
+
|
822
|
+
\begin_layout LyX-Code
|
823
|
+
h2 = { dog: Pochi, cat: Tama }
|
824
|
+
\end_layout
|
825
|
+
|
826
|
+
\begin_layout LyX-Code
|
827
|
+
#=> {:dog=>#<Dog:0x9c214ac>, :cat=>#<Cat:0x98efb80>}
|
828
|
+
\end_layout
|
829
|
+
|
830
|
+
\begin_layout LyX-Code
|
831
|
+
h2[:dog]
|
832
|
+
\end_layout
|
833
|
+
|
834
|
+
\begin_layout LyX-Code
|
835
|
+
#=> #<Dog:0x9c214ac>
|
836
|
+
\end_layout
|
837
|
+
|
838
|
+
\begin_layout Subsection*
|
839
|
+
Code blocks and Closures
|
840
|
+
\end_layout
|
841
|
+
|
842
|
+
\begin_layout Standard
|
843
|
+
|
844
|
+
\emph on
|
845
|
+
\color red
|
846
|
+
Code blocks
|
847
|
+
\emph default
|
848
|
+
\color inherit
|
849
|
+
, or simply
|
850
|
+
\emph on
|
851
|
+
\color red
|
852
|
+
blocks
|
853
|
+
\emph default
|
854
|
+
\color inherit
|
855
|
+
, are pieces of code enclosed by
|
856
|
+
\family typewriter
|
857
|
+
\color red
|
858
|
+
do
|
859
|
+
\family default
|
860
|
+
\color inherit
|
861
|
+
/
|
862
|
+
\family typewriter
|
863
|
+
\color red
|
864
|
+
end
|
865
|
+
\family default
|
866
|
+
\color inherit
|
867
|
+
pair, or by curly brackets
|
868
|
+
\family typewriter
|
869
|
+
\color red
|
870
|
+
{}
|
871
|
+
\family default
|
872
|
+
\color inherit
|
873
|
+
.
|
874
|
+
Code blocks can be passed to methods:
|
875
|
+
\end_layout
|
876
|
+
|
877
|
+
\begin_layout LyX-Code
|
878
|
+
[1, 2, 3, 4].map
|
879
|
+
\color red
|
880
|
+
{ |
|
881
|
+
\color inherit
|
882
|
+
n
|
883
|
+
\color red
|
884
|
+
|
|
885
|
+
\color inherit
|
886
|
+
n + 3
|
887
|
+
\color red
|
888
|
+
}
|
889
|
+
\end_layout
|
890
|
+
|
891
|
+
\begin_layout LyX-Code
|
892
|
+
#=> [4, 5, 6, 7]
|
893
|
+
\end_layout
|
894
|
+
|
895
|
+
\begin_layout LyX-Code
|
896
|
+
my_array.
|
897
|
+
\color red
|
898
|
+
each
|
899
|
+
\color inherit
|
900
|
+
do
|
901
|
+
\color red
|
902
|
+
|
|
903
|
+
\color inherit
|
904
|
+
member
|
905
|
+
\color red
|
906
|
+
|
|
907
|
+
\color inherit
|
908
|
+
member.speak! end
|
909
|
+
\end_layout
|
910
|
+
|
911
|
+
\begin_layout LyX-Code
|
912
|
+
#=> Bow wow!
|
913
|
+
\end_layout
|
914
|
+
|
915
|
+
\begin_layout LyX-Code
|
916
|
+
Meow
|
917
|
+
\end_layout
|
918
|
+
|
919
|
+
\begin_layout Standard
|
920
|
+
In the first case, '
|
921
|
+
\family typewriter
|
922
|
+
map
|
923
|
+
\family default
|
924
|
+
' method was passed a block specifying addition of 3.
|
925
|
+
In the second case, '
|
926
|
+
\family typewriter
|
927
|
+
each
|
928
|
+
\family default
|
929
|
+
' method was passed a block calling
|
930
|
+
\family typewriter
|
931
|
+
speak!
|
932
|
+
\family default
|
933
|
+
method on the array elements.
|
934
|
+
Please note the pipe, or vertical line charecters (
|
935
|
+
\color red
|
936
|
+
|
|
937
|
+
\color inherit
|
938
|
+
), that delimit the block arguments (both blocks above happen to have only
|
939
|
+
one argument).
|
940
|
+
Code blocks can be understood as anonymous functions – a way of specifying
|
941
|
+
an operation, when one does not want to write a method for it.
|
942
|
+
Their semantics corresponds to
|
943
|
+
\emph on
|
944
|
+
lambda calculus
|
945
|
+
\emph default
|
946
|
+
.
|
947
|
+
\end_layout
|
948
|
+
|
949
|
+
\begin_layout Subsubsection*
|
950
|
+
Return values
|
951
|
+
\end_layout
|
952
|
+
|
953
|
+
\begin_layout Standard
|
954
|
+
Code blocks (and actually, all Ruby statements) have return value.
|
955
|
+
With code blocks, the return value will typically be the last statement:
|
956
|
+
\end_layout
|
957
|
+
|
958
|
+
\begin_layout LyX-Code
|
959
|
+
[1, 2, 3, 4].map { |v|
|
960
|
+
\end_layout
|
961
|
+
|
962
|
+
\begin_layout LyX-Code
|
963
|
+
v + 3 # this value will be ignored
|
964
|
+
\end_layout
|
965
|
+
|
966
|
+
\begin_layout LyX-Code
|
967
|
+
v - 1 # last value of the block will be returned
|
968
|
+
\end_layout
|
969
|
+
|
970
|
+
\begin_layout LyX-Code
|
971
|
+
}
|
972
|
+
\end_layout
|
973
|
+
|
974
|
+
\begin_layout LyX-Code
|
975
|
+
#=> [0, 1, 2, 3]
|
976
|
+
\end_layout
|
977
|
+
|
978
|
+
\begin_layout Subsubsection*
|
979
|
+
Closures
|
980
|
+
\end_layout
|
981
|
+
|
982
|
+
\begin_layout Standard
|
983
|
+
A block packaged for future use is called a
|
984
|
+
\emph on
|
985
|
+
\color red
|
986
|
+
closure
|
987
|
+
\emph default
|
988
|
+
\color inherit
|
989
|
+
.
|
990
|
+
Ruby closures come in two flavors:
|
991
|
+
\family typewriter
|
992
|
+
\color red
|
993
|
+
proc
|
994
|
+
\family default
|
995
|
+
\color inherit
|
996
|
+
and
|
997
|
+
\family typewriter
|
998
|
+
\color red
|
999
|
+
lambda
|
1000
|
+
\family default
|
1001
|
+
\color inherit
|
1002
|
+
.
|
1003
|
+
They are created by passing a block to the
|
1004
|
+
\family typewriter
|
1005
|
+
proc
|
1006
|
+
\family default
|
1007
|
+
/
|
1008
|
+
\family typewriter
|
1009
|
+
lambda
|
1010
|
+
\family default
|
1011
|
+
keyword:
|
1012
|
+
\end_layout
|
1013
|
+
|
1014
|
+
\begin_layout LyX-Code
|
1015
|
+
my_proc =
|
1016
|
+
\color red
|
1017
|
+
proc
|
1018
|
+
\color inherit
|
1019
|
+
do |organism| organism.speak! end
|
1020
|
+
\end_layout
|
1021
|
+
|
1022
|
+
\begin_layout LyX-Code
|
1023
|
+
#=> #<Proc:0x952674c@(irb):136>
|
1024
|
+
\end_layout
|
1025
|
+
|
1026
|
+
\begin_layout LyX-Code
|
1027
|
+
my_lambda =
|
1028
|
+
\color red
|
1029
|
+
lambda
|
1030
|
+
\color inherit
|
1031
|
+
do |organism| organism.speak! end
|
1032
|
+
\end_layout
|
1033
|
+
|
1034
|
+
\begin_layout LyX-Code
|
1035
|
+
#=> #<Proc:0x942faf0@(irb):137 (lambda)>
|
1036
|
+
\end_layout
|
1037
|
+
|
1038
|
+
\begin_layout Standard
|
1039
|
+
Once defined, they can be reused in code.
|
1040
|
+
Notice the ampersand (
|
1041
|
+
\family typewriter
|
1042
|
+
\color red
|
1043
|
+
&
|
1044
|
+
\family default
|
1045
|
+
\color inherit
|
1046
|
+
) indicating block reuse:
|
1047
|
+
\end_layout
|
1048
|
+
|
1049
|
+
\begin_layout LyX-Code
|
1050
|
+
my_array.each
|
1051
|
+
\color red
|
1052
|
+
&
|
1053
|
+
\color inherit
|
1054
|
+
my_proc
|
1055
|
+
\end_layout
|
1056
|
+
|
1057
|
+
\begin_layout LyX-Code
|
1058
|
+
#=> Bow wow!
|
1059
|
+
\end_layout
|
1060
|
+
|
1061
|
+
\begin_layout LyX-Code
|
1062
|
+
Meow
|
1063
|
+
\end_layout
|
1064
|
+
|
1065
|
+
\begin_layout LyX-Code
|
1066
|
+
my_array.each &my_lambda
|
1067
|
+
\end_layout
|
1068
|
+
|
1069
|
+
\begin_layout LyX-Code
|
1070
|
+
#=> Bow wow!
|
1071
|
+
\end_layout
|
1072
|
+
|
1073
|
+
\begin_layout LyX-Code
|
1074
|
+
Meow
|
1075
|
+
\end_layout
|
1076
|
+
|
1077
|
+
\begin_layout Standard
|
1078
|
+
Closures can also be called alone, a little bit like methods:
|
1079
|
+
\end_layout
|
1080
|
+
|
1081
|
+
\begin_layout LyX-Code
|
1082
|
+
my_proc.
|
1083
|
+
\color red
|
1084
|
+
call
|
1085
|
+
\color inherit
|
1086
|
+
( Pochi )
|
1087
|
+
\end_layout
|
1088
|
+
|
1089
|
+
\begin_layout LyX-Code
|
1090
|
+
#=> Bow wow!
|
1091
|
+
\end_layout
|
1092
|
+
|
1093
|
+
\begin_layout LyX-Code
|
1094
|
+
my_lambda.call( Tama )
|
1095
|
+
\end_layout
|
1096
|
+
|
1097
|
+
\begin_layout LyX-Code
|
1098
|
+
#=> Meow
|
1099
|
+
\end_layout
|
1100
|
+
|
1101
|
+
\begin_layout Standard
|
1102
|
+
Instead of
|
1103
|
+
\family typewriter
|
1104
|
+
call
|
1105
|
+
\family default
|
1106
|
+
keyword, you can just use dot before the parenthesis to call closures:
|
1107
|
+
\end_layout
|
1108
|
+
|
1109
|
+
\begin_layout LyX-Code
|
1110
|
+
my_proc
|
1111
|
+
\color red
|
1112
|
+
.
|
1113
|
+
\color inherit
|
1114
|
+
( Tama )
|
1115
|
+
\end_layout
|
1116
|
+
|
1117
|
+
\begin_layout LyX-Code
|
1118
|
+
#=> Meow
|
1119
|
+
\end_layout
|
1120
|
+
|
1121
|
+
\begin_layout LyX-Code
|
1122
|
+
my_lambda.( Pochi )
|
1123
|
+
\end_layout
|
1124
|
+
|
1125
|
+
\begin_layout LyX-Code
|
1126
|
+
#=> Bow wow!
|
1127
|
+
\end_layout
|
1128
|
+
|
1129
|
+
\begin_layout Standard
|
1130
|
+
Differences between
|
1131
|
+
\family typewriter
|
1132
|
+
proc
|
1133
|
+
\family default
|
1134
|
+
and
|
1135
|
+
\family typewriter
|
1136
|
+
lambda
|
1137
|
+
\family default
|
1138
|
+
closures are minor.
|
1139
|
+
For
|
1140
|
+
\family typewriter
|
1141
|
+
YNelson
|
1142
|
+
\family default
|
1143
|
+
users, the most noticeable difference will be, that
|
1144
|
+
\family typewriter
|
1145
|
+
proc
|
1146
|
+
\family default
|
1147
|
+
less finicky about its arguments than
|
1148
|
+
\family typewriter
|
1149
|
+
lambda
|
1150
|
+
\family default
|
1151
|
+
:
|
1152
|
+
\end_layout
|
1153
|
+
|
1154
|
+
\begin_layout LyX-Code
|
1155
|
+
my_proc.( Tama, "garbage" )
|
1156
|
+
\end_layout
|
1157
|
+
|
1158
|
+
\begin_layout LyX-Code
|
1159
|
+
#=> Meow
|
1160
|
+
\end_layout
|
1161
|
+
|
1162
|
+
\begin_layout LyX-Code
|
1163
|
+
my_lambda.( Tama, "garbage" )
|
1164
|
+
\end_layout
|
1165
|
+
|
1166
|
+
\begin_layout LyX-Code
|
1167
|
+
#=> ArgumentError: wrong number of arguments (2 for 1)
|
1168
|
+
\end_layout
|
1169
|
+
|
1170
|
+
\begin_layout Subsection*
|
1171
|
+
Passing arguments
|
1172
|
+
\end_layout
|
1173
|
+
|
1174
|
+
\begin_layout Standard
|
1175
|
+
Earlier, we have defined method
|
1176
|
+
\family typewriter
|
1177
|
+
average
|
1178
|
+
\family default
|
1179
|
+
, expecting two arguments.
|
1180
|
+
If wrong number of arguments is supplied,
|
1181
|
+
\family typewriter
|
1182
|
+
ArgumentError
|
1183
|
+
\family default
|
1184
|
+
will ensue:
|
1185
|
+
\end_layout
|
1186
|
+
|
1187
|
+
\begin_layout LyX-Code
|
1188
|
+
average( 3, 5 )
|
1189
|
+
\end_layout
|
1190
|
+
|
1191
|
+
\begin_layout LyX-Code
|
1192
|
+
#=> 4
|
1193
|
+
\end_layout
|
1194
|
+
|
1195
|
+
\begin_layout LyX-Code
|
1196
|
+
average( 3, 5, 8 )
|
1197
|
+
\end_layout
|
1198
|
+
|
1199
|
+
\begin_layout LyX-Code
|
1200
|
+
#=> ArgumentError: wrong number of arguments (3 for 2)
|
1201
|
+
\end_layout
|
1202
|
+
|
1203
|
+
\begin_layout Standard
|
1204
|
+
Obviously, this is not a very nice behavior when it comes to averages.
|
1205
|
+
It is a general situation, that when calling more advanced methods, we
|
1206
|
+
need to modify their behavior, or pass more complicated structures to them.
|
1207
|
+
This is seen eg.
|
1208
|
+
with
|
1209
|
+
\family typewriter
|
1210
|
+
YNelson::Transition
|
1211
|
+
\family default
|
1212
|
+
constructors, and will be further encountered in
|
1213
|
+
\family typewriter
|
1214
|
+
YCell
|
1215
|
+
\family default
|
1216
|
+
and
|
1217
|
+
\family typewriter
|
1218
|
+
YChem
|
1219
|
+
\family default
|
1220
|
+
DSLs.
|
1221
|
+
Furthermore,
|
1222
|
+
\family typewriter
|
1223
|
+
YNelson
|
1224
|
+
\family default
|
1225
|
+
users have to be able to write their own closures, because that is how
|
1226
|
+
|
1227
|
+
\emph on
|
1228
|
+
functions
|
1229
|
+
\emph default
|
1230
|
+
of
|
1231
|
+
\emph on
|
1232
|
+
functional transitions
|
1233
|
+
\emph default
|
1234
|
+
are specified.
|
1235
|
+
In other words,
|
1236
|
+
\family typewriter
|
1237
|
+
\series bold
|
1238
|
+
YNelson
|
1239
|
+
\family default
|
1240
|
+
users have to master argument passing from both user and programmer side
|
1241
|
+
\series default
|
1242
|
+
.
|
1243
|
+
There is no way around this.
|
1244
|
+
With functional Petri nets, one cannot avoid writing functions.
|
1245
|
+
It is possible to avoid using
|
1246
|
+
\family typewriter
|
1247
|
+
YNelson
|
1248
|
+
\family default
|
1249
|
+
, but it is not possible to avoid learning to write functions.
|
1250
|
+
Every simulator of functional Petri nets brings with itself some sort of
|
1251
|
+
function language, which one has to learn.
|
1252
|
+
With
|
1253
|
+
\family typewriter
|
1254
|
+
YNelson
|
1255
|
+
\family default
|
1256
|
+
, this is the language of Ruby closures.
|
1257
|
+
\end_layout
|
1258
|
+
|
1259
|
+
\begin_layout Subsubsection*
|
1260
|
+
Optional arguments
|
1261
|
+
\end_layout
|
1262
|
+
|
1263
|
+
\begin_layout Standard
|
1264
|
+
Arguments with prescribed default value are optional.
|
1265
|
+
Let us write an improved
|
1266
|
+
\family typewriter
|
1267
|
+
average
|
1268
|
+
\family default
|
1269
|
+
method that can accept either 2 or 3 arguments:
|
1270
|
+
\end_layout
|
1271
|
+
|
1272
|
+
\begin_layout LyX-Code
|
1273
|
+
def average( a, b, c
|
1274
|
+
\color red
|
1275
|
+
=
|
1276
|
+
\color inherit
|
1277
|
+
:pochi )
|
1278
|
+
\end_layout
|
1279
|
+
|
1280
|
+
\begin_layout LyX-Code
|
1281
|
+
|
1282
|
+
\color red
|
1283
|
+
#
|
1284
|
+
\color inherit
|
1285
|
+
If c argument was not given, :pochi symbol will be assigned
|
1286
|
+
\end_layout
|
1287
|
+
|
1288
|
+
\begin_layout LyX-Code
|
1289
|
+
# to c by default.
|
1290
|
+
\end_layout
|
1291
|
+
|
1292
|
+
\begin_layout LyX-Code
|
1293
|
+
|
1294
|
+
\color red
|
1295
|
+
if
|
1296
|
+
\color inherit
|
1297
|
+
c
|
1298
|
+
\color red
|
1299
|
+
==
|
1300
|
+
\color inherit
|
1301
|
+
:pochi
|
1302
|
+
\color red
|
1303
|
+
then
|
1304
|
+
\color inherit
|
1305
|
+
# only 2 arguments were supplied
|
1306
|
+
\end_layout
|
1307
|
+
|
1308
|
+
\begin_layout LyX-Code
|
1309
|
+
( a + b ).to_f / 2
|
1310
|
+
\end_layout
|
1311
|
+
|
1312
|
+
\begin_layout LyX-Code
|
1313
|
+
|
1314
|
+
\color red
|
1315
|
+
else
|
1316
|
+
\color inherit
|
1317
|
+
# 3 arguments were supplied
|
1318
|
+
\end_layout
|
1319
|
+
|
1320
|
+
\begin_layout LyX-Code
|
1321
|
+
( a + b + c ).to_f / 3
|
1322
|
+
\end_layout
|
1323
|
+
|
1324
|
+
\begin_layout LyX-Code
|
1325
|
+
|
1326
|
+
\color red
|
1327
|
+
end
|
1328
|
+
\end_layout
|
1329
|
+
|
1330
|
+
\begin_layout LyX-Code
|
1331
|
+
end
|
1332
|
+
\end_layout
|
1333
|
+
|
1334
|
+
\begin_layout LyX-Code
|
1335
|
+
#=> nil
|
1336
|
+
\end_layout
|
1337
|
+
|
1338
|
+
\begin_layout LyX-Code
|
1339
|
+
average( 3, 5 )
|
1340
|
+
\end_layout
|
1341
|
+
|
1342
|
+
\begin_layout LyX-Code
|
1343
|
+
#=> 4
|
1344
|
+
\end_layout
|
1345
|
+
|
1346
|
+
\begin_layout LyX-Code
|
1347
|
+
average( 3, 5, 8 )
|
1348
|
+
\end_layout
|
1349
|
+
|
1350
|
+
\begin_layout LyX-Code
|
1351
|
+
#=> 5.333333333333333
|
1352
|
+
\end_layout
|
1353
|
+
|
1354
|
+
\begin_layout LyX-Code
|
1355
|
+
average( 1, 2, 3, 4 )
|
1356
|
+
\end_layout
|
1357
|
+
|
1358
|
+
\begin_layout LyX-Code
|
1359
|
+
#=> ArgumentError: wrong number of arguments (4 for 3)
|
1360
|
+
\end_layout
|
1361
|
+
|
1362
|
+
\begin_layout Standard
|
1363
|
+
The default value for
|
1364
|
+
\family typewriter
|
1365
|
+
c
|
1366
|
+
\family default
|
1367
|
+
argument is prescribed using single equals sign (
|
1368
|
+
\family typewriter
|
1369
|
+
\color red
|
1370
|
+
=
|
1371
|
+
\family default
|
1372
|
+
\color inherit
|
1373
|
+
).
|
1374
|
+
Apart from that, you can notice
|
1375
|
+
\family typewriter
|
1376
|
+
\color red
|
1377
|
+
if
|
1378
|
+
\family default
|
1379
|
+
\color inherit
|
1380
|
+
...
|
1381
|
+
|
1382
|
+
\family typewriter
|
1383
|
+
\color red
|
1384
|
+
then
|
1385
|
+
\family default
|
1386
|
+
\color inherit
|
1387
|
+
...
|
1388
|
+
|
1389
|
+
\family typewriter
|
1390
|
+
\color red
|
1391
|
+
else
|
1392
|
+
\family default
|
1393
|
+
\color inherit
|
1394
|
+
...
|
1395
|
+
|
1396
|
+
\family typewriter
|
1397
|
+
\color red
|
1398
|
+
end
|
1399
|
+
\family default
|
1400
|
+
\color inherit
|
1401
|
+
statement, which needs no explanation, equality test (double equals sign,
|
1402
|
+
|
1403
|
+
\family typewriter
|
1404
|
+
\color red
|
1405
|
+
==
|
1406
|
+
\family default
|
1407
|
+
\color inherit
|
1408
|
+
), used to test whether
|
1409
|
+
\family typewriter
|
1410
|
+
c
|
1411
|
+
\family default
|
1412
|
+
contains
|
1413
|
+
\family typewriter
|
1414
|
+
:pochi
|
1415
|
+
\family default
|
1416
|
+
symbol (indicating missing value), and comment character (octothorpe aka.
|
1417
|
+
sharp,
|
1418
|
+
\family typewriter
|
1419
|
+
\color red
|
1420
|
+
#
|
1421
|
+
\family default
|
1422
|
+
\color inherit
|
1423
|
+
).
|
1424
|
+
Comment character
|
1425
|
+
\family typewriter
|
1426
|
+
\color red
|
1427
|
+
#
|
1428
|
+
\family default
|
1429
|
+
\color inherit
|
1430
|
+
causes all characters until the end of the line to be ignored by Ruby.
|
1431
|
+
All code lines, exception the obvious ones, should have comments.
|
1432
|
+
\end_layout
|
1433
|
+
|
1434
|
+
\begin_layout Subsubsection*
|
1435
|
+
Variable-length argument lists
|
1436
|
+
\end_layout
|
1437
|
+
|
1438
|
+
\begin_layout Standard
|
1439
|
+
We will now improve our
|
1440
|
+
\family typewriter
|
1441
|
+
average
|
1442
|
+
\family default
|
1443
|
+
method, so that it can calculate averages of any number of arguments.
|
1444
|
+
For this, we will use asterisk (
|
1445
|
+
\family typewriter
|
1446
|
+
\color red
|
1447
|
+
*
|
1448
|
+
\family default
|
1449
|
+
\color inherit
|
1450
|
+
) syntactic modifier, also known as
|
1451
|
+
\emph on
|
1452
|
+
splash
|
1453
|
+
\emph default
|
1454
|
+
.
|
1455
|
+
The asterisk will cause a method to collect the arguments into an array.
|
1456
|
+
Let's try it out first:
|
1457
|
+
\end_layout
|
1458
|
+
|
1459
|
+
\begin_layout LyX-Code
|
1460
|
+
def examine_arguments( x,
|
1461
|
+
\color red
|
1462
|
+
*
|
1463
|
+
\color inherit
|
1464
|
+
aa )
|
1465
|
+
\end_layout
|
1466
|
+
|
1467
|
+
\begin_layout LyX-Code
|
1468
|
+
puts "x is a
|
1469
|
+
\color red
|
1470
|
+
#{
|
1471
|
+
\color inherit
|
1472
|
+
x.class
|
1473
|
+
\color red
|
1474
|
+
}
|
1475
|
+
\color inherit
|
1476
|
+
."
|
1477
|
+
\end_layout
|
1478
|
+
|
1479
|
+
\begin_layout LyX-Code
|
1480
|
+
puts "aa is #{aa.class} of #{aa.size} elements."
|
1481
|
+
\end_layout
|
1482
|
+
|
1483
|
+
\begin_layout LyX-Code
|
1484
|
+
end
|
1485
|
+
\end_layout
|
1486
|
+
|
1487
|
+
\begin_layout LyX-Code
|
1488
|
+
#=> nil
|
1489
|
+
\end_layout
|
1490
|
+
|
1491
|
+
\begin_layout Standard
|
1492
|
+
Method examine arguments takes one normal argument (
|
1493
|
+
\family typewriter
|
1494
|
+
x
|
1495
|
+
\family default
|
1496
|
+
), and collects the rest of the arguments into an array (
|
1497
|
+
\family typewriter
|
1498
|
+
aa
|
1499
|
+
\family default
|
1500
|
+
), thanks to the splash modifier.
|
1501
|
+
(Apart from that, you can notice string interpolation using
|
1502
|
+
\family typewriter
|
1503
|
+
#{ ...
|
1504
|
+
}
|
1505
|
+
\family default
|
1506
|
+
notation in the above code.) Then it prints the class of
|
1507
|
+
\family typewriter
|
1508
|
+
x
|
1509
|
+
\family default
|
1510
|
+
, class of
|
1511
|
+
\family typewriter
|
1512
|
+
aa
|
1513
|
+
\family default
|
1514
|
+
(which should be an array), and the number of elements after
|
1515
|
+
\family typewriter
|
1516
|
+
x
|
1517
|
+
\family default
|
1518
|
+
.
|
1519
|
+
\end_layout
|
1520
|
+
|
1521
|
+
\begin_layout LyX-Code
|
1522
|
+
examine_arguments( 1 )
|
1523
|
+
\end_layout
|
1524
|
+
|
1525
|
+
\begin_layout LyX-Code
|
1526
|
+
#=> x is a Fixnum.
|
1527
|
+
\end_layout
|
1528
|
+
|
1529
|
+
\begin_layout LyX-Code
|
1530
|
+
aa is Array of 0 elements.
|
1531
|
+
\end_layout
|
1532
|
+
|
1533
|
+
\begin_layout LyX-Code
|
1534
|
+
nil
|
1535
|
+
\end_layout
|
1536
|
+
|
1537
|
+
\begin_layout LyX-Code
|
1538
|
+
examine_arguments( :hello, :pochi, 3, 5, "garbage" )
|
1539
|
+
\end_layout
|
1540
|
+
|
1541
|
+
\begin_layout LyX-Code
|
1542
|
+
#=> x is a Symbol.
|
1543
|
+
\end_layout
|
1544
|
+
|
1545
|
+
\begin_layout LyX-Code
|
1546
|
+
aa is Array of 4 elements.
|
1547
|
+
\end_layout
|
1548
|
+
|
1549
|
+
\begin_layout LyX-Code
|
1550
|
+
nil
|
1551
|
+
\end_layout
|
1552
|
+
|
1553
|
+
\begin_layout Standard
|
1554
|
+
With this, we can go on to define our improved average method:
|
1555
|
+
\end_layout
|
1556
|
+
|
1557
|
+
\begin_layout LyX-Code
|
1558
|
+
def average( *aa )
|
1559
|
+
\end_layout
|
1560
|
+
|
1561
|
+
\begin_layout LyX-Code
|
1562
|
+
aa.
|
1563
|
+
\color red
|
1564
|
+
reduce( :+ )
|
1565
|
+
\color inherit
|
1566
|
+
.to_f / aa.size
|
1567
|
+
\end_layout
|
1568
|
+
|
1569
|
+
\begin_layout LyX-Code
|
1570
|
+
end
|
1571
|
+
\end_layout
|
1572
|
+
|
1573
|
+
\begin_layout LyX-Code
|
1574
|
+
#=> nil
|
1575
|
+
\end_layout
|
1576
|
+
|
1577
|
+
\begin_layout LyX-Code
|
1578
|
+
average 3, 5, 7, 11
|
1579
|
+
\end_layout
|
1580
|
+
|
1581
|
+
\begin_layout LyX-Code
|
1582
|
+
#=> 6.5
|
1583
|
+
\end_layout
|
1584
|
+
|
1585
|
+
\begin_layout Standard
|
1586
|
+
You can also newly notice
|
1587
|
+
\family typewriter
|
1588
|
+
reduce( :+ )
|
1589
|
+
\family default
|
1590
|
+
method, used to calculate the sum of the
|
1591
|
+
\family typewriter
|
1592
|
+
aa
|
1593
|
+
\family default
|
1594
|
+
array.
|
1595
|
+
To also practice closures, let us define a lambda doing the same as the
|
1596
|
+
|
1597
|
+
\family typewriter
|
1598
|
+
average
|
1599
|
+
\family default
|
1600
|
+
method above:
|
1601
|
+
\end_layout
|
1602
|
+
|
1603
|
+
\begin_layout LyX-Code
|
1604
|
+
avg = lambda { |*aa| aa.reduce( :+ ).to_f / aa.size }
|
1605
|
+
\end_layout
|
1606
|
+
|
1607
|
+
\begin_layout LyX-Code
|
1608
|
+
#=> #<Proc:0x9dbd220@(irb):208 (lambda)>
|
1609
|
+
\end_layout
|
1610
|
+
|
1611
|
+
\begin_layout LyX-Code
|
1612
|
+
avg.( 11, 7, 5, 3 )
|
1613
|
+
\end_layout
|
1614
|
+
|
1615
|
+
\begin_layout LyX-Code
|
1616
|
+
#=> 6.5
|
1617
|
+
\end_layout
|
1618
|
+
|
1619
|
+
\begin_layout Subsubsection*
|
1620
|
+
Named arguments
|
1621
|
+
\end_layout
|
1622
|
+
|
1623
|
+
\begin_layout Standard
|
1624
|
+
The main purpose of named arguments is to make the interface (or DSL) easier
|
1625
|
+
to remember, and the code easier to read.
|
1626
|
+
Easy-to-read code is a crucial requirement for scalable development.
|
1627
|
+
In Ruby methods, named arguments can be specified
|
1628
|
+
\color red
|
1629
|
+
as hash pairs in the method call
|
1630
|
+
\color inherit
|
1631
|
+
:
|
1632
|
+
\end_layout
|
1633
|
+
|
1634
|
+
\begin_layout LyX-Code
|
1635
|
+
def density( length: 1, width: 1, height: 1, weight: 1 )
|
1636
|
+
\end_layout
|
1637
|
+
|
1638
|
+
\begin_layout LyX-Code
|
1639
|
+
weight.to_f / ( length * width * height )
|
1640
|
+
\end_layout
|
1641
|
+
|
1642
|
+
\begin_layout LyX-Code
|
1643
|
+
end
|
1644
|
+
\end_layout
|
1645
|
+
|
1646
|
+
\begin_layout LyX-Code
|
1647
|
+
#=> nil
|
1648
|
+
\end_layout
|
1649
|
+
|
1650
|
+
\begin_layout LyX-Code
|
1651
|
+
density( length: 2, width: 2, height: 2, weight: 10 )
|
1652
|
+
\end_layout
|
1653
|
+
|
1654
|
+
\begin_layout LyX-Code
|
1655
|
+
#=> 1.25
|
1656
|
+
\end_layout
|
1657
|
+
|
1658
|
+
\begin_layout Standard
|
1659
|
+
The above method calculates mean density of boxes of certain height, width,
|
1660
|
+
length and weight.
|
1661
|
+
Double splash (
|
1662
|
+
\family typewriter
|
1663
|
+
\color red
|
1664
|
+
**
|
1665
|
+
\family default
|
1666
|
+
\color inherit
|
1667
|
+
) can be used to collect all the options in a hash.
|
1668
|
+
Let's use it to define a closure that does exactly the same thing as the
|
1669
|
+
method
|
1670
|
+
\family typewriter
|
1671
|
+
density
|
1672
|
+
\family default
|
1673
|
+
we have just defined, in a slightly different way:
|
1674
|
+
\end_layout
|
1675
|
+
|
1676
|
+
\begin_layout LyX-Code
|
1677
|
+
dens_closure =
|
1678
|
+
\color red
|
1679
|
+
->
|
1680
|
+
\color inherit
|
1681
|
+
**nn do
|
1682
|
+
\end_layout
|
1683
|
+
|
1684
|
+
\begin_layout LyX-Code
|
1685
|
+
nn[:weight].to_f / ( nn[:length] * nn[:width] * nn[:height] ) end
|
1686
|
+
\end_layout
|
1687
|
+
|
1688
|
+
\begin_layout LyX-Code
|
1689
|
+
#=> #<Proc:0x9a5d60c@(irb):241 (lambda)>
|
1690
|
+
\end_layout
|
1691
|
+
|
1692
|
+
\begin_layout LyX-Code
|
1693
|
+
dens_closure.( length: 2, width: 2, height: 2, weight: 10 )
|
1694
|
+
\end_layout
|
1695
|
+
|
1696
|
+
\begin_layout LyX-Code
|
1697
|
+
#=> 1.25
|
1698
|
+
\end_layout
|
1699
|
+
|
1700
|
+
\begin_layout Standard
|
1701
|
+
Above, note the alternative syntax for lambdas:
|
1702
|
+
\family typewriter
|
1703
|
+
-> arg do ...
|
1704
|
+
end
|
1705
|
+
\family default
|
1706
|
+
is the same as
|
1707
|
+
\family typewriter
|
1708
|
+
lambda do |arg| ...
|
1709
|
+
end
|
1710
|
+
\family default
|
1711
|
+
.
|
1712
|
+
Having hereby introduced the named arguments, let us notice hash-collecting
|
1713
|
+
behavior for square bracket (
|
1714
|
+
\family typewriter
|
1715
|
+
[]
|
1716
|
+
\family default
|
1717
|
+
) array constructor syntax.
|
1718
|
+
\end_layout
|
1719
|
+
|
1720
|
+
\begin_layout Subsubsection*
|
1721
|
+
Hash-collecting behavior of square brackets
|
1722
|
+
\end_layout
|
1723
|
+
|
1724
|
+
\begin_layout Standard
|
1725
|
+
In more complicated method argument structures, it can be advantageous to
|
1726
|
+
take use of the hash-collecting by square brackets.
|
1727
|
+
It is normal for curly braces to create hashes:
|
1728
|
+
\end_layout
|
1729
|
+
|
1730
|
+
\begin_layout LyX-Code
|
1731
|
+
h = { length: 2, width: 3, height: 4 }
|
1732
|
+
\end_layout
|
1733
|
+
|
1734
|
+
\begin_layout LyX-Code
|
1735
|
+
#=> {:length=>2, :width=>3, :height=>4}
|
1736
|
+
\end_layout
|
1737
|
+
|
1738
|
+
\begin_layout LyX-Code
|
1739
|
+
h.class
|
1740
|
+
\end_layout
|
1741
|
+
|
1742
|
+
\begin_layout LyX-Code
|
1743
|
+
#=> Hash
|
1744
|
+
\end_layout
|
1745
|
+
|
1746
|
+
\begin_layout Standard
|
1747
|
+
However, square brackets, that generally create arrays, are also
|
1748
|
+
\color red
|
1749
|
+
able to collect hashes just like the argument fields with named arguments
|
1750
|
+
\color inherit
|
1751
|
+
:
|
1752
|
+
\end_layout
|
1753
|
+
|
1754
|
+
\begin_layout LyX-Code
|
1755
|
+
a0 = [ 1, 2, 3 ]
|
1756
|
+
\end_layout
|
1757
|
+
|
1758
|
+
\begin_layout LyX-Code
|
1759
|
+
#=> [1, 2, 3]
|
1760
|
+
\end_layout
|
1761
|
+
|
1762
|
+
\begin_layout LyX-Code
|
1763
|
+
a0.class
|
1764
|
+
\end_layout
|
1765
|
+
|
1766
|
+
\begin_layout LyX-Code
|
1767
|
+
#=> Array
|
1768
|
+
\end_layout
|
1769
|
+
|
1770
|
+
\begin_layout LyX-Code
|
1771
|
+
a1 = [ 1, 2, 3, length: 2, width: 3, height: 4 ]
|
1772
|
+
\end_layout
|
1773
|
+
|
1774
|
+
\begin_layout LyX-Code
|
1775
|
+
#=> [1, 2, 3, {:length=>2, :width=>3, :height=>4}]
|
1776
|
+
\end_layout
|
1777
|
+
|
1778
|
+
\begin_layout LyX-Code
|
1779
|
+
a1.class
|
1780
|
+
\end_layout
|
1781
|
+
|
1782
|
+
\begin_layout LyX-Code
|
1783
|
+
#=> Array
|
1784
|
+
\end_layout
|
1785
|
+
|
1786
|
+
\begin_layout LyX-Code
|
1787
|
+
a1.map &:class
|
1788
|
+
\end_layout
|
1789
|
+
|
1790
|
+
\begin_layout LyX-Code
|
1791
|
+
#=> [Fixnum, Fixnum, Fixnum, Hash]
|
1792
|
+
\end_layout
|
1793
|
+
|
1794
|
+
\begin_layout LyX-Code
|
1795
|
+
a1[-1]
|
1796
|
+
\end_layout
|
1797
|
+
|
1798
|
+
\begin_layout LyX-Code
|
1799
|
+
#=> {:length=>2, :width=>3, :height=>4}
|
1800
|
+
\end_layout
|
1801
|
+
|
1802
|
+
\begin_layout Standard
|
1803
|
+
In other words, if there are any trailing
|
1804
|
+
\family typewriter
|
1805
|
+
key / value
|
1806
|
+
\family default
|
1807
|
+
pairs inside square brackets, they will be collected into a hash, which
|
1808
|
+
will become the last element of the array.
|
1809
|
+
This possibility to mix ordered elements with
|
1810
|
+
\family typewriter
|
1811
|
+
key / value
|
1812
|
+
\family default
|
1813
|
+
pairs is used eg.
|
1814
|
+
in
|
1815
|
+
\family typewriter
|
1816
|
+
YCell
|
1817
|
+
\family default
|
1818
|
+
|
1819
|
+
\family typewriter
|
1820
|
+
enzyme
|
1821
|
+
\family default
|
1822
|
+
constructor method.
|
1823
|
+
\end_layout
|
1824
|
+
|
1825
|
+
\begin_layout Subsection*
|
1826
|
+
Arity
|
1827
|
+
\end_layout
|
1828
|
+
|
1829
|
+
\begin_layout Standard
|
1830
|
+
Every closure and every method has arity, which is basically the number
|
1831
|
+
of input arguments.
|
1832
|
+
(Closures with 0 arguments are null
|
1833
|
+
\emph on
|
1834
|
+
ary
|
1835
|
+
\emph default
|
1836
|
+
, with 1 argument un
|
1837
|
+
\emph on
|
1838
|
+
ary
|
1839
|
+
\emph default
|
1840
|
+
, with 2 arguments bin
|
1841
|
+
\emph on
|
1842
|
+
ary
|
1843
|
+
\emph default
|
1844
|
+
, with 3 arguments tern
|
1845
|
+
\emph on
|
1846
|
+
ary
|
1847
|
+
\emph default
|
1848
|
+
etc.
|
1849
|
+
– therefrom
|
1850
|
+
\emph on
|
1851
|
+
arity
|
1852
|
+
\emph default
|
1853
|
+
.)
|
1854
|
+
\end_layout
|
1855
|
+
|
1856
|
+
\begin_layout LyX-Code
|
1857
|
+
doubler = lambda { |a| a * 2 }
|
1858
|
+
\end_layout
|
1859
|
+
|
1860
|
+
\begin_layout LyX-Code
|
1861
|
+
#=> #<Proc:0xa19b5b8@(irb):1 (lambda)>
|
1862
|
+
\end_layout
|
1863
|
+
|
1864
|
+
\begin_layout LyX-Code
|
1865
|
+
doubler.call( 3 )
|
1866
|
+
\end_layout
|
1867
|
+
|
1868
|
+
\begin_layout LyX-Code
|
1869
|
+
#=> 6
|
1870
|
+
\end_layout
|
1871
|
+
|
1872
|
+
\begin_layout LyX-Code
|
1873
|
+
doubler.arity
|
1874
|
+
\end_layout
|
1875
|
+
|
1876
|
+
\begin_layout LyX-Code
|
1877
|
+
#=> 1
|
1878
|
+
\end_layout
|
1879
|
+
|
1880
|
+
\begin_layout LyX-Code
|
1881
|
+
adder = lambda { |p, q| p + q }
|
1882
|
+
\end_layout
|
1883
|
+
|
1884
|
+
\begin_layout LyX-Code
|
1885
|
+
#=> #<Proc:0xa27d940@(irb):6 (lambda)>
|
1886
|
+
\end_layout
|
1887
|
+
|
1888
|
+
\begin_layout LyX-Code
|
1889
|
+
adder.call( 5, 6 )
|
1890
|
+
\end_layout
|
1891
|
+
|
1892
|
+
\begin_layout LyX-Code
|
1893
|
+
#=> 11
|
1894
|
+
\end_layout
|
1895
|
+
|
1896
|
+
\begin_layout LyX-Code
|
1897
|
+
adder.arity
|
1898
|
+
\end_layout
|
1899
|
+
|
1900
|
+
\begin_layout LyX-Code
|
1901
|
+
#=> 2
|
1902
|
+
\end_layout
|
1903
|
+
|
1904
|
+
\begin_layout LyX-Code
|
1905
|
+
scaler = lambda { |number, p, q| number * (q / p) }
|
1906
|
+
\end_layout
|
1907
|
+
|
1908
|
+
\begin_layout LyX-Code
|
1909
|
+
#=> #<Proc:0xa2825e4@(irb):7 (lambda)>
|
1910
|
+
\end_layout
|
1911
|
+
|
1912
|
+
\begin_layout LyX-Code
|
1913
|
+
scaler.call( 10, 2, 3 )
|
1914
|
+
\end_layout
|
1915
|
+
|
1916
|
+
\begin_layout LyX-Code
|
1917
|
+
#=> 15
|
1918
|
+
\end_layout
|
1919
|
+
|
1920
|
+
\begin_layout LyX-Code
|
1921
|
+
scaler.arity
|
1922
|
+
\end_layout
|
1923
|
+
|
1924
|
+
\begin_layout LyX-Code
|
1925
|
+
#=> 3
|
1926
|
+
\end_layout
|
1927
|
+
|
1928
|
+
\begin_layout LyX-Code
|
1929
|
+
constant_function = lambda { 42 }
|
1930
|
+
\end_layout
|
1931
|
+
|
1932
|
+
\begin_layout LyX-Code
|
1933
|
+
#=> #<Proc:0xa2825e4@(irb):7 (lambda)>
|
1934
|
+
\end_layout
|
1935
|
+
|
1936
|
+
\begin_layout LyX-Code
|
1937
|
+
constant_function.call
|
1938
|
+
\end_layout
|
1939
|
+
|
1940
|
+
\begin_layout LyX-Code
|
1941
|
+
#=> 42
|
1942
|
+
\end_layout
|
1943
|
+
|
1944
|
+
\begin_layout LyX-Code
|
1945
|
+
constant_function.arity
|
1946
|
+
\end_layout
|
1947
|
+
|
1948
|
+
\begin_layout LyX-Code
|
1949
|
+
#=> 0
|
1950
|
+
\end_layout
|
1951
|
+
|
1952
|
+
\begin_layout Standard
|
1953
|
+
Closures / methods with variable length arguments indicate this by reporting
|
1954
|
+
negative arity:
|
1955
|
+
\end_layout
|
1956
|
+
|
1957
|
+
\begin_layout LyX-Code
|
1958
|
+
summation = lambda { |*array| array.reduce( :+ ) }
|
1959
|
+
\end_layout
|
1960
|
+
|
1961
|
+
\begin_layout LyX-Code
|
1962
|
+
#=> #<Proc:0xa296ddc@(irb):9 (lambda)>
|
1963
|
+
\end_layout
|
1964
|
+
|
1965
|
+
\begin_layout LyX-Code
|
1966
|
+
summation.call( 1, 2, 3, 4 )
|
1967
|
+
\end_layout
|
1968
|
+
|
1969
|
+
\begin_layout LyX-Code
|
1970
|
+
#=> 10
|
1971
|
+
\end_layout
|
1972
|
+
|
1973
|
+
\begin_layout LyX-Code
|
1974
|
+
summation.arity
|
1975
|
+
\end_layout
|
1976
|
+
|
1977
|
+
\begin_layout LyX-Code
|
1978
|
+
#=> -1
|
1979
|
+
\end_layout
|
1980
|
+
|
1981
|
+
\begin_layout LyX-Code
|
1982
|
+
array_scale = lambda { |*a, coeff| a.map { |e| e * coeff } }
|
1983
|
+
\end_layout
|
1984
|
+
|
1985
|
+
\begin_layout LyX-Code
|
1986
|
+
#=> #<Proc:0xa2a9edc@(irb):12 (lambda)>
|
1987
|
+
\end_layout
|
1988
|
+
|
1989
|
+
\begin_layout LyX-Code
|
1990
|
+
array_scale.call( 1, 2, 3, 4, 7 )
|
1991
|
+
\end_layout
|
1992
|
+
|
1993
|
+
\begin_layout LyX-Code
|
1994
|
+
#=> [7, 14, 21, 28]
|
1995
|
+
\end_layout
|
1996
|
+
|
1997
|
+
\begin_layout LyX-Code
|
1998
|
+
array_scale.arity
|
1999
|
+
\end_layout
|
2000
|
+
|
2001
|
+
\begin_layout LyX-Code
|
2002
|
+
#=> -2
|
2003
|
+
\end_layout
|
2004
|
+
|
2005
|
+
\begin_layout Subsection*
|
2006
|
+
Return value
|
2007
|
+
\end_layout
|
2008
|
+
|
2009
|
+
\begin_layout Standard
|
2010
|
+
The last statement in a closure / method becomes the return value.
|
2011
|
+
In methods and lambda-type closures, return statement can also be used
|
2012
|
+
explicitly:
|
2013
|
+
\end_layout
|
2014
|
+
|
2015
|
+
\begin_layout LyX-Code
|
2016
|
+
divider = lambda { |u, v|
|
2017
|
+
\end_layout
|
2018
|
+
|
2019
|
+
\begin_layout LyX-Code
|
2020
|
+
if v == 0 then
|
2021
|
+
\end_layout
|
2022
|
+
|
2023
|
+
\begin_layout LyX-Code
|
2024
|
+
return :division_by_zero # explicit return statement
|
2025
|
+
\end_layout
|
2026
|
+
|
2027
|
+
\begin_layout LyX-Code
|
2028
|
+
end
|
2029
|
+
\end_layout
|
2030
|
+
|
2031
|
+
\begin_layout LyX-Code
|
2032
|
+
u / v # implicit return value - last statement of the closure
|
2033
|
+
\end_layout
|
2034
|
+
|
2035
|
+
\begin_layout LyX-Code
|
2036
|
+
}
|
2037
|
+
\end_layout
|
2038
|
+
|
2039
|
+
\begin_layout LyX-Code
|
2040
|
+
#=> #<Proc:0xa21e878@(irb):15 (lambda)>
|
2041
|
+
\end_layout
|
2042
|
+
|
2043
|
+
\begin_layout LyX-Code
|
2044
|
+
divider.call( 15, 3 )
|
2045
|
+
\end_layout
|
2046
|
+
|
2047
|
+
\begin_layout LyX-Code
|
2048
|
+
#=> 5
|
2049
|
+
\end_layout
|
2050
|
+
|
2051
|
+
\begin_layout LyX-Code
|
2052
|
+
divider.call( 15, 0 )
|
2053
|
+
\end_layout
|
2054
|
+
|
2055
|
+
\begin_layout LyX-Code
|
2056
|
+
#=> :division_by_zero
|
2057
|
+
\end_layout
|
2058
|
+
|
2059
|
+
\begin_layout LyX-Code
|
2060
|
+
experimental_closure = proc {
|
2061
|
+
\end_layout
|
2062
|
+
|
2063
|
+
\begin_layout LyX-Code
|
2064
|
+
1 # this value will be ignored
|
2065
|
+
\end_layout
|
2066
|
+
|
2067
|
+
\begin_layout LyX-Code
|
2068
|
+
3 # this value will be ignored, too
|
2069
|
+
\end_layout
|
2070
|
+
|
2071
|
+
\begin_layout LyX-Code
|
2072
|
+
42 # this value will be discarded as well
|
2073
|
+
\end_layout
|
2074
|
+
|
2075
|
+
\begin_layout LyX-Code
|
2076
|
+
41 } # this value will be returned
|
2077
|
+
\end_layout
|
2078
|
+
|
2079
|
+
\begin_layout LyX-Code
|
2080
|
+
#=> #<Proc:0xa249460@(irb):28>
|
2081
|
+
\end_layout
|
2082
|
+
|
2083
|
+
\begin_layout LyX-Code
|
2084
|
+
experimental_closure.call
|
2085
|
+
\end_layout
|
2086
|
+
|
2087
|
+
\begin_layout LyX-Code
|
2088
|
+
#=> 41
|
2089
|
+
\end_layout
|
2090
|
+
|
2091
|
+
\begin_layout LyX-Code
|
2092
|
+
experimental_lambda = lambda {
|
2093
|
+
\end_layout
|
2094
|
+
|
2095
|
+
\begin_layout LyX-Code
|
2096
|
+
1 # this value will be ignored
|
2097
|
+
\end_layout
|
2098
|
+
|
2099
|
+
\begin_layout LyX-Code
|
2100
|
+
return 3 # this value will be returned
|
2101
|
+
\end_layout
|
2102
|
+
|
2103
|
+
\begin_layout LyX-Code
|
2104
|
+
7 # execution will never get here at all
|
2105
|
+
\end_layout
|
2106
|
+
|
2107
|
+
\begin_layout LyX-Code
|
2108
|
+
}
|
2109
|
+
\end_layout
|
2110
|
+
|
2111
|
+
\begin_layout LyX-Code
|
2112
|
+
#=> #<Proc:0xa3200dc@(irb):38 (lambda)>
|
2113
|
+
\end_layout
|
2114
|
+
|
2115
|
+
\begin_layout LyX-Code
|
2116
|
+
experimental_lambda.call
|
2117
|
+
\end_layout
|
2118
|
+
|
2119
|
+
\begin_layout LyX-Code
|
2120
|
+
#=> 3
|
2121
|
+
\end_layout
|
2122
|
+
|
2123
|
+
\begin_layout Subsection*
|
2124
|
+
Return value arity
|
2125
|
+
\end_layout
|
2126
|
+
|
2127
|
+
\begin_layout Standard
|
2128
|
+
It is possible to return more than one value.
|
2129
|
+
For example:
|
2130
|
+
\end_layout
|
2131
|
+
|
2132
|
+
\begin_layout LyX-Code
|
2133
|
+
multiplication_table = lambda { |number|
|
2134
|
+
\end_layout
|
2135
|
+
|
2136
|
+
\begin_layout LyX-Code
|
2137
|
+
[1, 2, 3, 4, 5]
|
2138
|
+
\end_layout
|
2139
|
+
|
2140
|
+
\begin_layout LyX-Code
|
2141
|
+
.map { |element| element * number }
|
2142
|
+
\end_layout
|
2143
|
+
|
2144
|
+
\begin_layout LyX-Code
|
2145
|
+
}
|
2146
|
+
\end_layout
|
2147
|
+
|
2148
|
+
\begin_layout LyX-Code
|
2149
|
+
#=> #<Proc:0xa36a0d8@(irb):55 (lambda)>
|
2150
|
+
\end_layout
|
2151
|
+
|
2152
|
+
\begin_layout Standard
|
2153
|
+
This method returns 5 values.
|
2154
|
+
We can receive them by using a simultaneous assignment statement:
|
2155
|
+
\end_layout
|
2156
|
+
|
2157
|
+
\begin_layout LyX-Code
|
2158
|
+
by_one, by_two, by_three, by_four, by_five = multiplication_table.call( 7
|
2159
|
+
)
|
2160
|
+
\end_layout
|
2161
|
+
|
2162
|
+
\begin_layout LyX-Code
|
2163
|
+
#=> [7, 14, 21, 28, 35]
|
2164
|
+
\end_layout
|
2165
|
+
|
2166
|
+
\begin_layout LyX-Code
|
2167
|
+
by_one
|
2168
|
+
\end_layout
|
2169
|
+
|
2170
|
+
\begin_layout LyX-Code
|
2171
|
+
#=> 7
|
2172
|
+
\end_layout
|
2173
|
+
|
2174
|
+
\begin_layout LyX-Code
|
2175
|
+
by_two
|
2176
|
+
\end_layout
|
2177
|
+
|
2178
|
+
\begin_layout LyX-Code
|
2179
|
+
#=> 14
|
2180
|
+
\end_layout
|
2181
|
+
|
2182
|
+
\begin_layout LyX-Code
|
2183
|
+
by_five
|
2184
|
+
\end_layout
|
2185
|
+
|
2186
|
+
\begin_layout LyX-Code
|
2187
|
+
#=> 35
|
2188
|
+
\end_layout
|
2189
|
+
|
2190
|
+
\begin_layout Standard
|
2191
|
+
Or we can simply collect them in an array:
|
2192
|
+
\end_layout
|
2193
|
+
|
2194
|
+
\begin_layout LyX-Code
|
2195
|
+
collection = multiplication_table.( 3 )
|
2196
|
+
\end_layout
|
2197
|
+
|
2198
|
+
\begin_layout LyX-Code
|
2199
|
+
#=> [3, 6, 9, 12, 15]
|
2200
|
+
\end_layout
|
2201
|
+
|
2202
|
+
\begin_layout Standard
|
2203
|
+
In
|
2204
|
+
\family typewriter
|
2205
|
+
YNelson
|
2206
|
+
\family default
|
2207
|
+
, it sometimes becomes necessary to write closures with higher return arity
|
2208
|
+
(returning more than one value).
|
2209
|
+
This is normally done by returning an array.
|
2210
|
+
Also, lambda return statement can be used to return multiple values:
|
2211
|
+
\end_layout
|
2212
|
+
|
2213
|
+
\begin_layout LyX-Code
|
2214
|
+
constant_vector = lambda { return 1, 2, 3 }
|
2215
|
+
\end_layout
|
2216
|
+
|
2217
|
+
\begin_layout LyX-Code
|
2218
|
+
#=> #<Proc:0xa3cb338@(irb):72 (lambda)>
|
2219
|
+
\end_layout
|
2220
|
+
|
2221
|
+
\begin_layout LyX-Code
|
2222
|
+
x, y, z = constant_vector.call
|
2223
|
+
\end_layout
|
2224
|
+
|
2225
|
+
\begin_layout LyX-Code
|
2226
|
+
#=> [1, 2, 3]
|
2227
|
+
\end_layout
|
2228
|
+
|
2229
|
+
\begin_layout LyX-Code
|
2230
|
+
x
|
2231
|
+
\end_layout
|
2232
|
+
|
2233
|
+
\begin_layout LyX-Code
|
2234
|
+
#=> 1
|
2235
|
+
\end_layout
|
2236
|
+
|
2237
|
+
\begin_layout LyX-Code
|
2238
|
+
y
|
2239
|
+
\end_layout
|
2240
|
+
|
2241
|
+
\begin_layout LyX-Code
|
2242
|
+
#=> 2
|
2243
|
+
\end_layout
|
2244
|
+
|
2245
|
+
\begin_layout LyX-Code
|
2246
|
+
z
|
2247
|
+
\end_layout
|
2248
|
+
|
2249
|
+
\begin_layout LyX-Code
|
2250
|
+
#=> 3
|
2251
|
+
\end_layout
|
2252
|
+
|
2253
|
+
\end_body
|
2254
|
+
\end_document
|