rabbit-slide-niku-osc15do-elixir 2015.06.13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7bd442f6d44db8a35a0019209eced049ecb21fbd
4
+ data.tar.gz: 7203a56ea86cc7db037a19d80ba1f5560951170a
5
+ SHA512:
6
+ metadata.gz: 8654377df3caf75cfd63abb32b2530f411b4f9951b458060c303e36c6a5fb50293655deea39dc6d79afc254533fd2b4204e541bc0373d7ca28305afea652b18e
7
+ data.tar.gz: 935e49f33777cee447b55d236f81552a3ce09051304f3506d612031816e856dd938416e6e6176c59a397b6b19e993d43dfa68c2d5baf8efa9abab47990592500
data/.rabbit ADDED
@@ -0,0 +1 @@
1
+ osc2015hokkaido-elixir.md
data/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # OSC 2015 Hokkaido Elixir
2
+
3
+ 2015-06-13 OSC Hokkaido 2015 で発表する [プログラミング言語 Elxiir](https://www.ospn.jp/osc2015-do/modules/eguide/event.php?eid=37) の資料
4
+
5
+ ## 作者向け
6
+
7
+ ### 表示
8
+
9
+ rake
10
+
11
+ ### 公開
12
+
13
+ rake publish
14
+
15
+ ## 閲覧者向け
16
+
17
+ ### インストール
18
+
19
+ gem install rabbit-slide-niku-osc15do-elixir
20
+
21
+ ### 表示
22
+
23
+ rabbit rabbit-slide-niku-osc15do-elixir.gem
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require "rabbit/task/slide"
2
+
3
+ # Edit ./config.yaml to customize meta data
4
+
5
+ spec = nil
6
+ Rabbit::Task::Slide.new do |task|
7
+ spec = task.spec
8
+ # spec.files += Dir.glob("doc/**/*.*")
9
+ # spec.files -= Dir.glob("private/**/*.*")
10
+ # spec.add_runtime_dependency("YOUR THEME")
11
+ end
12
+
13
+ desc "Tag #{spec.version}"
14
+ task :tag do
15
+ sh("git", "tag", "-a", spec.version.to_s, "-m", "Publish #{spec.version}")
16
+ sh("git", "push", "--tags")
17
+ end
data/config.yaml ADDED
@@ -0,0 +1,20 @@
1
+ ---
2
+ id: osc15do-elixir
3
+ base_name: osc2015hokkaido-elixir
4
+ tags:
5
+ - elixir
6
+ presentation_date: 2015/06/13
7
+ version: 2015.06.13
8
+ licenses: []
9
+ slideshare_id:
10
+ speaker_deck_id:
11
+ ustream_id:
12
+ vimeo_id:
13
+ youtube_id:
14
+ author:
15
+ markup_language: :markdown
16
+ name: niku
17
+ email: niku@niku.name
18
+ rubygems_user: niku
19
+ slideshare_user:
20
+ speaker_deck_user: niku
@@ -0,0 +1,751 @@
1
+ # プログラミング言語Elixir
2
+
3
+ author
4
+ niku
5
+ date
6
+ 2015/06/13
7
+ allotted-time
8
+ 45m
9
+
10
+ # 資料の目的
11
+
12
+ - Elixir を触ってみることができるよな気分になること
13
+ - Elixir でやりたいことがあったとき,どの辺を眺めたり探せばよいか,推測できるようになること
14
+
15
+ # Elixirの特徴
16
+
17
+
18
+ [Elixir の特徴 - Qiita](http://qiita.com/niku/items/7c61d6a6af38896ac603)
19
+ <http://qiita.com/niku/items/7c61d6a6af38896ac603>
20
+
21
+ # Elixirの特徴
22
+
23
+ - スケールしやすさ
24
+ - 対障害性
25
+ - 関数型プログラミング
26
+ - 拡張しやすさと DSL
27
+ - 成長するエコシステム
28
+ - 対話型開発
29
+ - Erlang 互換
30
+
31
+ # ぼくがえりくさーですきなとこ
32
+
33
+ - なじみのある文面 <- [今日これ]
34
+ - ErlangVMで処理
35
+
36
+ # インストール
37
+
38
+ [Installing Elixir - Elixir](http://elixir-lang.org/install.html)
39
+
40
+ <http://elixir-lang.org/install.html>
41
+
42
+ - OSX
43
+ - Unix
44
+ - Windows
45
+
46
+ # iexコマンド
47
+
48
+
49
+ [IEx](http://elixir-lang.org/docs/stable/iex/IEx.html)
50
+
51
+ <http://elixir-lang.org/docs/stable/iex/IEx.html>
52
+
53
+ - `iex` というコマンドで REPL が使える
54
+ - `iex` 内で打ち間違えたとき `#iex:break` と打つとやりなおせる
55
+
56
+ # 値
57
+
58
+
59
+ [Basic types - Elixir](http://elixir-lang.org/getting-started/basic-types.html)
60
+
61
+ <http://elixir-lang.org/getting-started/basic-types.html>
62
+
63
+ # 値
64
+
65
+
66
+ 1 # 整数
67
+ 0x1F # 整数
68
+ 1.0 # 小数
69
+ true # ブーリアン
70
+ :atom # アトム
71
+ "elixir" # 文字列
72
+ [1, 2, 3] # リスト
73
+ {1, 2, 3} # タプル
74
+
75
+ # 整数
76
+
77
+ 1 # 整数 <-
78
+ 0x1F # 整数 <-
79
+ 1.0 # 小数
80
+ true # ブーリアン
81
+ :atom # アトム
82
+ "elixir" # 文字列
83
+ [1, 2, 3] # リスト
84
+ {1, 2, 3} # タプル
85
+
86
+ # 整数
87
+
88
+ 1 # => 1
89
+ 0x1F # => 31
90
+ 1 + 2 # => 3
91
+ 5 * 5 # => 25
92
+ 10 / 2 # => 5.0
93
+ div(10, 2) # => 5
94
+ rem(10, 3) # => 1
95
+
96
+ # 整数
97
+
98
+
99
+ # 同じものを指す
100
+ div(10, 2) # => 5
101
+ div 10, 2 # => 5
102
+ Kernel.div(10, 2) # => 5
103
+ # 同じものを指す
104
+ 1 + 2 # => 3
105
+ Kernel.+(1, 2) # => 3
106
+ Kernel.+ 1, 2 # => 3
107
+
108
+ # Elixirの関数
109
+
110
+
111
+ - Elixir では(ErlangVMでは) `モジュール名.関数名/引数の数` で関数を指定する
112
+ - 例えば `Kernel.div(10, 2)` は `Kernel.div/2`
113
+
114
+ # 関数の調べかた
115
+
116
+
117
+ `1 + 1` の `+` について知りたい場合
118
+
119
+ - `1 + 1` は `Kernel.+(1, 1)` のこと
120
+ - モジュールは `Kernel` 関数は `+` 引数の数は `2` つだから `Kernel.+/2` だな
121
+ - iex から `h Kernel.+/2` とするとドキュメントが引ける
122
+
123
+ # 関数の調べかた
124
+
125
+ iex(1)> h Kernel.+/2
126
+
127
+ def +(left, right)
128
+
129
+ Arithmetic plus.
130
+
131
+ Allowed in guard tests. Inlined by the compiler.
132
+
133
+ Examples
134
+
135
+ ┃ iex> 1 + 2
136
+ ┃ 3
137
+
138
+ # 関数の調べかた
139
+
140
+
141
+ `h Kernel.+` と引数の数を省略すると, `Kernel.+` で,引数の数を問わないで探す
142
+
143
+ iex(3)> h Kernel.+
144
+ def +(value)
145
+ (省略)
146
+ def +(left, right)
147
+ (省略)
148
+
149
+ # 関数の調べかた
150
+
151
+ web から
152
+
153
+ [Elixir v1.0.4 Documentation](http://elixir-lang.org/docs/stable/elixir/)
154
+ <http://elixir-lang.org/docs/stable/elixir/>
155
+
156
+ web 日本語版( @k1complete さん作)
157
+
158
+ [elixirリファレンスのぺーじ](http://ns.maqcsa.org/elixir/docs/)
159
+ <http://ns.maqcsa.org/elixir/docs/>
160
+
161
+ # 関数の調べかた
162
+
163
+ [Elixir - iexでの日本語版ヘルプの使い方 - Qiita](http://qiita.com/k1complete/items/511ef32b63869bc48d02)
164
+ <http://qiita.com/k1complete/items/511ef32b63869bc48d02>
165
+
166
+ h で表示する内容を日本語にもできるみたい(試していない)
167
+
168
+ # 整数を操作する関数
169
+
170
+
171
+ - [Kernel](http://elixir-lang.org/docs/stable/elixir/Kernel.html) に `+/2` `-/2` `div/2` などがある
172
+ - [Integer](http://elixir-lang.org/docs/stable/elixir/Integer.html) に `is_odd/1` などがある
173
+
174
+ # 小数
175
+
176
+ 1 # 整数
177
+ 0x1F # 整数
178
+ 1.0 # 小数 <-
179
+ true # ブーリアン
180
+ :atom # アトム
181
+ "elixir" # 文字列
182
+ [1, 2, 3] # リスト
183
+ {1, 2, 3} # タプル
184
+
185
+ # 小数
186
+
187
+ 1.0 # => 1.0
188
+ 1.0e-5 # => 1.0e-5
189
+ 1.0e-5 === 0.00001 # => true
190
+ round(3.58) # => 4
191
+ trunc(3.58) # => 3
192
+
193
+ # 小数を操作する関数
194
+
195
+ - [Kernel](http://elixir-lang.org/docs/stable/elixir/Kernel.html) に `round/1` `trunc/1` などがある
196
+ - [Float](http://elixir-lang.org/docs/stable/elixir/Float.html) に `ceil/1` や `foor/1` などがある
197
+
198
+ # ブーリアン
199
+
200
+ 1 # 整数
201
+ 0x1F # 整数
202
+ 1.0 # 小数
203
+ true # ブーリアン <-
204
+ :atom # アトム
205
+ "elixir" # 文字列
206
+ [1, 2, 3] # リスト
207
+ {1, 2, 3} # タプル
208
+
209
+ # ブーリアン
210
+
211
+
212
+ true # => true
213
+ false # => false
214
+ !true # => false
215
+
216
+ # ブーリアンを操作する関数
217
+
218
+ みつからなかった!
219
+
220
+ # アトム
221
+
222
+ 1 # 整数
223
+ 0x1F # 整数
224
+ 1.0 # 小数
225
+ true # ブーリアン
226
+ :atom # アトム <-
227
+ "elixir" # 文字列
228
+ [1, 2, 3] # リスト
229
+ {1, 2, 3} # タプル
230
+
231
+ # アトム
232
+
233
+ 自分の名前が自分の値を表すような定数.他の言語だとシンボルと呼ばれるようなもの.
234
+
235
+ :foo # => :foo
236
+ :"foo-bar" # => :"foo-bar"
237
+ # ブーリアン値はアトムでした
238
+ :true === true # => true
239
+ :false === false # => true
240
+
241
+ # アトムを操作する関数
242
+
243
+ - [Atom](http://elixir-lang.org/docs/v1.0/elixir/Atom.html) にシンボルから文字列に変換する関数がある
244
+
245
+ # 文字列
246
+
247
+ 1 # 整数
248
+ 0x1F # 整数
249
+ 1.0 # 小数
250
+ true # ブーリアン
251
+ :atom # アトム
252
+ "elixir" # 文字列 <-
253
+ [1, 2, 3] # リスト
254
+ {1, 2, 3} # タプル
255
+
256
+ # 文字列
257
+
258
+ [Binaries, strings and char lists - Elixir](http://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html)
259
+ <http://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html>
260
+
261
+ - Elixir では " でくくった文字列と ' でくくった文字列がある
262
+ - ほぼ全ての場合において " の方を利用する
263
+
264
+ # 文字列
265
+
266
+ "abc" # => "abc"
267
+ "こんにちは" # => "こんにちは"
268
+ "1 + 2 は #{ 1 + 2 } です" # => "1 + 2 は 3 です"
269
+ # Elixir では文字列はバイナリとして扱われる
270
+ is_binary("abc") # => true
271
+
272
+ # 文字列を操作する関数
273
+
274
+ byte_size("日本語") # => 9
275
+ String.length("日本語") # => 3
276
+ String.at("日本語", 1) # => "本"
277
+
278
+ - [Kernel](http://elixir-lang.org/docs/stable/elixir/Kernel.html) にバイナリを操作する関数がある
279
+ - [String](http://elixir-lang.org/docs/v1.0/elixir/String.html) モジュールに,UTF-8 エンコードされているバイナリをうまく扱う関数がある
280
+
281
+ # 複数の値を格納する値
282
+
283
+
284
+ 1 # 整数
285
+ 0x1F # 整数
286
+ 1.0 # 小数
287
+ true # ブーリアン
288
+ :atom # アトム
289
+ "elixir" # 文字列
290
+ [1, 2, 3] # リスト <-
291
+ {1, 2, 3} # タプル <-
292
+
293
+ # 複数の値を格納する値
294
+
295
+ [Basic types - Elixir](http://elixir-lang.org/getting-started/basic-types.html#%28linked%29-lists)
296
+ <http://elixir-lang.org/getting-started/basic-types.html#%28linked%29-lists>
297
+
298
+ [Keywords, maps and dicts - Elixir](http://elixir-lang.org/getting-started/maps-and-dicts.html)
299
+ <http://elixir-lang.org/getting-started/maps-and-dicts.html>
300
+
301
+ # 複数の値を格納する値
302
+
303
+ [1, 2, 3] # リスト <-
304
+ {1, 2, 3} # タプル
305
+ %{foo: "hoge", bar: "fuga"} # マップ
306
+ [{:foo, "hoge"},
307
+ {:bar, "fuga"},
308
+ {:foo, "moge"}] # キーワードリスト
309
+
310
+ # リスト
311
+
312
+ [1,2,3] # => [1, 2, 3]
313
+ [:a, "b", 'c'] # => [:a, "b", 'c']
314
+ [[:x], [:y, :z]] # => [[:x], [:y, :z]]
315
+
316
+ - `[]` でくくる
317
+ - いわゆる配列.値はなんでも,何個でも入る
318
+
319
+ # リストを操作する関数
320
+
321
+ Enum.map([1,2,3], fn(x) -> x * 2 end) # => [2, 4, 6]
322
+ List.last([4,5,6]) # => 6
323
+
324
+ - [Enum](http://elixir-lang.org/docs/stable/elixir/Enum.html) には,繰り返しについての関数がある
325
+ - [List](http://elixir-lang.org/docs/stable/elixir/List.html) には,List特有の関数がある
326
+
327
+ まず Enum を探すのがよい
328
+
329
+ # タプル
330
+
331
+ [1, 2, 3] # リスト
332
+ {1, 2, 3} # タプル <-
333
+ %{foo: "hoge", bar: "fuga"} # マップ
334
+ [{:foo, "hoge"},
335
+ {:bar, "fuga"},
336
+ {:foo, "moge"}] # キーワードリスト
337
+
338
+ # タプル
339
+
340
+ {:a, 1} # => {:a, 1}
341
+ {"x", "y", "z"} # => {"x", "y", "z"}
342
+
343
+ - `{}` でくくる
344
+ - 中に入る個数が決まった入れ物
345
+
346
+ # タプルを操作する関数
347
+
348
+ elem({:a, "abc"}, 1) # => abc
349
+ Tuple.delete_at({"x", "y", "z"}, 1) # => {"x", "z"}
350
+
351
+ - [Kernel](http://elixir-lang.org/docs/stable/elixir/Kernel.html) にはタプルの値を取得する関数がある
352
+ - [Tuple](http://elixir-lang.org/docs/stable/elixir/Tuple.html) にはタプル特有な関数がある
353
+
354
+ # マップ
355
+
356
+ [1, 2, 3] # リスト
357
+ {1, 2, 3} # タプル
358
+ %{foo: "hoge", bar: "fuga"} # マップ <-
359
+ [{:foo, "hoge"},
360
+ {:bar, "fuga"},
361
+ {:foo, "moge"}] # キーワードリスト
362
+
363
+ # マップ
364
+
365
+ %{:a => 1, :b => 2} # => %{a: 1, b: 2}
366
+ %{a: 1, b: 2} # => %{a: 1, b: 2}
367
+ %{:a => 1, :b => 2, :a => 3} # => %{a: 3, b: 2}
368
+
369
+ - `%{}` でくくる
370
+ - キーと,それに対応する値を一組に持ついわゆるキーバリューストア
371
+ - キーは重複して定義できず,上書きされる
372
+
373
+ # マップを操作する関数
374
+
375
+ Enum.any?(%{a: 1, b: 2}, fn({k,_v}) -> k === :b end) # => true
376
+ Dict.update!(%{a: 1, b: 2}, :a, fn(v) -> v + 10 end) # => %{a: 11, b: 2}
377
+ Map.new # => %{}
378
+
379
+ - [Enum](http://elixir-lang.org/docs/stable/elixir/Enum.html) には,繰り返しについての関数がある
380
+ - [Dict](http://elixir-lang.org/docs/stable/elixir/Dict.html) には,とあるキーととある値が関連づいているようなデータについての関数がある
381
+ - [Map](http://elixir-lang.org/docs/stable/elixir/Map.html) には,Map 特有の関数がある
382
+
383
+ Enum -> Dict -> Map の順番で探すとよい
384
+
385
+ # キーワードリスト
386
+
387
+ [1, 2, 3] # リスト
388
+ {1, 2, 3} # タプル
389
+ %{foo: "hoge", bar: "fuga"} # マップ
390
+ [{:foo, "hoge"},
391
+ {:bar, "fuga"},
392
+ {:foo, "moge"}] # キーワードリスト <-
393
+
394
+ # キーワードリスト
395
+
396
+ [{:foo, "x"}, {:bar, "y"}] # => [foo: "x", bar: "y"]
397
+ [foo: "x", bar: "y"] # => [foo: "x", bar: "y"]
398
+ [{:foo, "x"}, {:bar, "y"}, {:foo, "z"}] # => [foo: "x", bar: "y", foo: "z"]
399
+
400
+ - 1 つめの要素がアトム,2 つめの要素が任意の値になっているタプルを持つ配列
401
+ - Map とは異なり,同じ名前のキーを 2 つ保持することができる
402
+ - キーワード引数としての利用が多い
403
+
404
+ # キーワードリストを操作する関数
405
+
406
+ Keyword.get_values([foo: "x", bar: "y", foo: "z"], :foo) # => ["x", "z"]
407
+
408
+ 特定のユースケースで多用されるため, Keyword モジュールにある関数で処理することが多い
409
+
410
+ - [Enum](http://elixir-lang.org/docs/stable/elixir/Enum.html) / [List](http://elixir-lang.org/docs/stable/elixir/List.html) / [Dict](http://elixir-lang.org/docs/stable/elixir/Dict.html) 利用可能
411
+ - [Keyword](http://elixir-lang.org/docs/stable/elixir/Keyword.html) には,キーワードリスト特有の処理がある
412
+
413
+ # モジュールと関数の定義
414
+
415
+
416
+ [Modules - Elixir](http://elixir-lang.org/getting-started/modules.html)
417
+ <http://elixir-lang.org/getting-started/modules.html>
418
+
419
+ # モジュールと関数の定義
420
+
421
+ defmodule MyOperand do
422
+ def plus(x, y) do
423
+ x + y
424
+ end
425
+
426
+ def minus(x, y) do
427
+ x - y
428
+ end
429
+ end
430
+ MyOperand.plus(1, 2) # => 3
431
+ MyOperand.minus(5, 3) # => 2
432
+
433
+ # モジュールと関数の定義
434
+
435
+ - モジュールは,関数をあるグループにまとめて,探しやすくするためにある
436
+ - 自分達でモジュールを定義するには `defmodule` を使う
437
+ - 関数の定義は `def` を使う
438
+
439
+ # do-endはキーワードリストで実装されている
440
+
441
+ [case, cond and if - Elixir](http://elixir-lang.org/getting-started/case-cond-and-if.html#do%2Fend-blocks)
442
+ <http://elixir-lang.org/getting-started/case-cond-and-if.html#do/end-blocks>
443
+
444
+ # do-endはキーワードリストで実装されている
445
+
446
+ if true do
447
+ "foo"
448
+ else
449
+ "bar"
450
+ end
451
+ if(true, do: "foo", else: "bar")
452
+ if(true, [{:do, "foo"}, {:else, "bar"}])
453
+
454
+ - Elixir の do xxx end は do: xxx というキーワード引数のシンタックスシュガー
455
+
456
+ # do-endはキーワードリストで実装されている
457
+
458
+ defmodule SingleLine
459
+ def bar do: "hoge"
460
+ def baz do: "fuga"
461
+ end
462
+
463
+ - 簡単な関数定義のときは `def` を 1 行で書くこともできる
464
+
465
+ # |>
466
+
467
+
468
+ [1,2,3,4,5,6] # => [1,2,3,4,5,6]
469
+ .map { |e| e + 1 } # => [2,3,4,5,6,7]
470
+ .select { |e| e.odd? } # => [3,5,7]
471
+ .select { |e| 3 < e } # => [5,7]
472
+
473
+ - データに対して処理を連続して行う(Rubyの場合)
474
+ - オブジェクトに関係つけている関数をオブジェクト経由で呼び出している
475
+
476
+ # |>
477
+
478
+ array = [1,2,3,4,5,6] # => [1,2,3,4,5,6]
479
+ mapped = Enum.map(array, fn(x) -> x + 1 end) # => [2,3,4,5,6,7]
480
+ odd = Enum.filter(mapped, fn(x) -> rem(x, 2) == 1 end) # => [3,5,7]
481
+ over3 = Enum.filter(odd, fn(x) -> 3 < x end) # => [5,7]
482
+ over3 # => [5,7]
483
+
484
+ - Elixir では,データに対しては関数が関係ついていない
485
+ - データに対して処理を連続して行いたいときは,返り値を次の関数へ引数として渡すことになる
486
+
487
+ # |>
488
+
489
+ Enum.filter(
490
+ Enum.filter(
491
+ Enum.map([1,2,3,4,5,6], fn(x) -> x + 1 end),
492
+ fn(x) -> rem(x, 2) == 1 end
493
+ ),
494
+ fn(x) -> 3 < x end
495
+ ) # => [5,7]
496
+
497
+ - インライン化して変数を消すことができた
498
+ - 処理順が上から下ではなく括弧の内側から外側になってしまった……
499
+
500
+ # |>
501
+
502
+ [1,2,3,4,5,6]
503
+ |> Enum.map(fn(x) -> x + 1 end)
504
+ |> Enum.filter(fn(x) -> rem(x, 2) == 1 end)
505
+ |> Enum.filter(fn(x) -> 3 < x end)
506
+ # => [5,7]
507
+
508
+ - Elixirには `|>` という演算子がある
509
+ - `|>` は,左(上)側の評価結果を,右側の関数の第一引数へと代入してくれる
510
+
511
+ # |>
512
+
513
+ "hoge" |> String.upcase |> String.replace("H", "M") # => MOGE
514
+
515
+ x1 = "hoge"
516
+ x2 = String.upcase(x1)
517
+ x3 = String.replace(x2, "H", "M") # => MOGE
518
+
519
+ - 上と下の式はほとんど同じ意味を持っている
520
+
521
+ # |>
522
+
523
+ - 「subject は第一引数に取る」という鉄則があるので, `|>` でデータを繋いでいくことができる
524
+ - 自分で関数を定義するときは,操作対象を第一引数に取るようにすると,Elixir Way に乗って `|>` を使いやすい
525
+
526
+ # 束縛
527
+
528
+
529
+ x = 1
530
+ x # => 1
531
+ y = :abc
532
+ y # => :abc
533
+ # ↑実質y1
534
+ y = :def
535
+ y # => :def
536
+ # ↑実質y2
537
+
538
+ # パターンマッチング
539
+
540
+ [h|t] = [1,2,3]
541
+ h # => 1
542
+ t # => [2,3]
543
+ {x, y} = {123, 456}
544
+ x # => 123
545
+ y # => 456
546
+ %{i: a} = %{i: "あい", j: "じぇい", k: "けい"}
547
+ a # => "あい"
548
+ %{i: b} = %{j: "じぇい", k: "けい"}
549
+ # => (MatchError) no match of right hand side value: %{j: "じぇい", k: "けい"}
550
+
551
+ - 複数の値を格納している値を,複数の変数に結びつけることができる
552
+
553
+ # パターンマッチング
554
+
555
+ [Pattern matching - Elixir](http://elixir-lang.org/getting-started/pattern-matching.html)
556
+ <http://elixir-lang.org/getting-started/pattern-matching.html>
557
+
558
+ # 文字へのパターンマッチング
559
+
560
+ <<h, t :: binary>> = "abcdef"
561
+ h # => 97
562
+ t # => "bcdef"
563
+ <<97>> === "a" # => true
564
+
565
+ - 文字にも同じようにパターンマッチングできる
566
+
567
+ # 匿名関数
568
+
569
+ [Basic types - Elixir](http://elixir-lang.org/getting-started/basic-types.html#anonymous-functions)
570
+ <http://elixir-lang.org/getting-started/basic-types.html#anonymous-functions>
571
+
572
+ # 匿名関数
573
+
574
+
575
+ add = fn(x, y) -> x + y end
576
+ add.(2, 3) # => 5
577
+
578
+ # 匿名関数
579
+
580
+ x1 = Enum.map([1,2,3], fn (x) -> x + 5 end)
581
+ x1 # => [6, 7, 8]
582
+ x2 = Enum.map([1,2,3], &(&1 + 5))
583
+ x2 # => [6, 7, 8]
584
+
585
+ - 関数(今回の例だと `Enum.map` )に匿名関数を渡して,やりたい事を書くときに使うことがほとんど
586
+ - `fn(x) -> x + 5 end` は `&(&1 + 5)` と書ける
587
+
588
+ # 制御構造
589
+
590
+ [case, cond and if - Elixir](http://elixir-lang.org/getting-started/case-cond-and-if.html)
591
+ <http://elixir-lang.org/getting-started/case-cond-and-if.html>
592
+
593
+ # 制御構造
594
+
595
+ if true do
596
+ "true"
597
+ else
598
+ "false"
599
+ end
600
+ # => "true"
601
+
602
+ - Elixir で `false` として扱われるのは, `false` と `nil` だけ
603
+
604
+ # 制御構造
605
+
606
+ x = if true do
607
+ "**true**"
608
+ else
609
+ "**false**"
610
+ end
611
+ x # => **true**
612
+
613
+ - IF 式は返り値を持つので,結果を変数に束縛することもできる
614
+
615
+ # 制御構造
616
+
617
+ x = 2
618
+ case x do
619
+ 1 -> "x => 1"
620
+ 2 -> "x => 2"
621
+ end
622
+ # => "x => 2"
623
+
624
+ - `true` / `false` 以外で分岐させたい場合は `case` を使う
625
+
626
+ # 制御構造
627
+
628
+ x = 2; y = 3; z = 2
629
+ case x do
630
+ y -> "x === y, #{y}"
631
+ z -> "x === z, #{z}"
632
+ end
633
+ # => "x === y, 2"
634
+
635
+ - `x` と `z` が等しいので "x `=` z" の方を期待していた
636
+
637
+ # 制御構造
638
+
639
+ x = 2; y = 3; z = 2
640
+ case x do
641
+ ^y -> "x === y, #{y}"
642
+ ^z -> "x === z, #{z}"
643
+ end
644
+ # => "x === z, 2"
645
+
646
+ - `y` の値が変わってほしくないという意思を伝える書き方 `^y` がある
647
+
648
+ # 制御構造
649
+
650
+ x = 3
651
+ case x do
652
+ 1 -> "x => 1"
653
+ 2 -> "x => 2"
654
+ end
655
+ # ** (CaseClauseError) no case clause matching: 3
656
+ # elixir_src.exs:2: (file)
657
+ # (elixir) lib/code.ex:307: Code.require_file/2
658
+
659
+ - `x` に 3 がきたときエラーでプロセスが落ちてしまった
660
+
661
+ # 制御構造
662
+
663
+ x = 3
664
+ case x do
665
+ 1 -> "x => 1"
666
+ 2 -> "x => 2"
667
+ _ -> "another x"
668
+ end
669
+ # => "another x"
670
+
671
+ - 最後に `true` か `_` を使ってマッチングすると未知の値も拾える
672
+
673
+ # 制御構造
674
+
675
+ しかし!ErlangVM では "Let it crash" という哲学があり,
676
+ 未知の値は無理にハンドリングせずに落としてしまう方が好ましい.
677
+
678
+ # 制御構造
679
+
680
+ プロセスは落ちてしまう.プロセスが落ちるとプログラム自体が終わる!と思うかもしれないが
681
+ ErlangVM ではプロセスが落ちてもプログラム自体を終わらせない方法が標準で用意されている.
682
+
683
+ # 制御構造
684
+
685
+ 今回は取り上げないが OTP や Supervisor について調べるとよい.
686
+ ひとまずここでは「予想できていること,状態についてだけ扱う」ということだけ覚えておいてほしい.
687
+
688
+ # 制御構造
689
+
690
+
691
+ x = 2
692
+ y = 3
693
+ result = case {x, y} do
694
+ {1, 2} -> :a
695
+ {1, 3} -> :b
696
+ {2, a} -> a
697
+ {3, _} -> :c
698
+ end
699
+ result # => 3
700
+
701
+ # 制御構造
702
+
703
+ x = 1
704
+ result = case x do
705
+ a when is_integer(x) -> a
706
+ a when is_float(x) -> trunc(a)
707
+ a when is_binary(x) -> String.to_integer(a)
708
+ end
709
+ result # => 1
710
+
711
+ # 制御構造
712
+
713
+ x = 1.1
714
+ result = case x do
715
+ a when is_integer(x) -> a
716
+ a when is_float(x) -> trunc(a)
717
+ a when is_binary(x) -> String.to_integer(a)
718
+ end
719
+ result # => 1
720
+
721
+ # 制御構造
722
+
723
+ x = "1"
724
+ result = case x do
725
+ a when is_integer(x) -> a
726
+ a when is_float(x) -> trunc(a)
727
+ a when is_binary(x) -> String.to_integer(a)
728
+ end
729
+ result # => 1
730
+
731
+ # 制御構造
732
+
733
+ [case, cond and if - Elixir](http://elixir-lang.org/getting-started/case-cond-and-if.html#expressions-in-guard-clauses)
734
+ <http://elixir-lang.org/getting-started/case-cond-and-if.html#expressions-in-guard-clauses>
735
+
736
+ - `guard` という方法を使えば,異なる型,例えば整数の `1` と小数点つきの数 `1.1` ,文字列 "1" を扱うこともできる
737
+
738
+ # 今日やったこと
739
+
740
+ - インタラクティブシェル iex
741
+ - ドキュメントの調べかた
742
+ - さまざまな値と,値を操作する関数
743
+ - パイプ演算子 |>
744
+ - パターンマッチング
745
+ - 制御構造
746
+
747
+ # 簡単なElixirのはじめかた
748
+
749
+ - 毎週木曜日にやっているsapporo.beamで聞こう
750
+ - http://sapporo-beam.github.io/
751
+ - オンライン参加も歓迎しております!
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rabbit-slide-niku-osc15do-elixir
3
+ version: !ruby/object:Gem::Version
4
+ version: 2015.06.13
5
+ platform: ruby
6
+ authors:
7
+ - niku
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rabbit
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.2
27
+ description: 2015-06-13 OSC Hokkaido 2015 で発表する [プログラミング言語 Elxiir](https://www.ospn.jp/osc2015-do/modules/eguide/event.php?eid=37)
28
+ の資料
29
+ email:
30
+ - niku@niku.name
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".rabbit"
36
+ - README.md
37
+ - Rakefile
38
+ - config.yaml
39
+ - osc2015hokkaido-elixir.md
40
+ - pdf/osc15do-elixir-osc2015hokkaido-elixir.pdf
41
+ homepage: http://slide.rabbit-shocker.org/authors/niku/osc15do-elixir/
42
+ licenses: []
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project:
60
+ rubygems_version: 2.4.5
61
+ signing_key:
62
+ specification_version: 4
63
+ summary: OSC 2015 Hokkaido Elixir
64
+ test_files: []