rabbit-slide-niku-techmix-hokkaido-2014-elixir 2014.12.06

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ad37c1d4fc969a978442ce330654f81b99b14513
4
+ data.tar.gz: 86d36e45242f1c25db9e27a16d4ee1535d87b084
5
+ SHA512:
6
+ metadata.gz: bc9cf815e99c05daaefbb825e2d757fdd4a53f52ae8b1025d92c0e0e6936ef64ce4cea6afdeffb3f82a87a621b262761a1632d940ab457e47de0d1f9c8033503
7
+ data.tar.gz: cdf0597ae309d005084c236a3c00a1dd026c9878c3924fff3939e42ab2202e6577e2db0b233d2b834165f16e212469396bf69994b4085a9a635baa97b1021944
data/.rabbit ADDED
@@ -0,0 +1 @@
1
+ techmix-hokkaido-2014-elixir.md
@@ -0,0 +1,23 @@
1
+ # Techmix Hokkaido 2014 Elixir
2
+
3
+ [Techmix Hokkaido 2014](http://www.techmix-hokkaido.com/) の発表に用いた資料です
4
+
5
+ ## 作者向け
6
+
7
+ ### 表示
8
+
9
+ rake
10
+
11
+ ### 公開
12
+
13
+ rake publish
14
+
15
+ ## 閲覧者向け
16
+
17
+ ### インストール
18
+
19
+ gem install rabbit-slide-niku-techmix-hokkaido-2014-elixir
20
+
21
+ ### 表示
22
+
23
+ rabbit rabbit-slide-niku-techmix-hokkaido-2014-elixir.gem
@@ -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
+ # task.spec.files += Dir.glob("doc/**/*.*")
9
+ # task.spec.files -= Dir.glob("private/**/*.*")
10
+ # task.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
@@ -0,0 +1,20 @@
1
+ ---
2
+ id: techmix-hokkaido-2014-elixir
3
+ base_name: techmix-hokkaido-2014-elixir
4
+ tags:
5
+ - elixir
6
+ presentation_date: 2014/12/06
7
+ version: 2014.12.06
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,695 @@
1
+ # Techmix Hokkaido 2014 Elixir
2
+
3
+ author
4
+ niku
5
+ date
6
+ 2014/12/06
7
+
8
+ allotted-time
9
+ : 20m
10
+
11
+ # 発表するひと
12
+
13
+ - ヽ(´・肉・`)ノ
14
+ - @niku_name
15
+
16
+ # コンサドーレ札幌アドベントカレンダー2014
17
+
18
+ http://www.adventar.org/calendars/406
19
+
20
+ # Elixriいつできたの?
21
+
22
+ - https://github.com/elixir-lang/elixir/
23
+ - 最初のコミットは *3 年前 (2011-01-09)*
24
+
25
+ # 誰が作りはじめたの?
26
+
27
+ - *Jose Valim* さん
28
+ - Ruby On Rails のコミッタ
29
+ - RubyKaigi2013 のキーノート
30
+ - http://gihyo.jp/news/report/01/rubykaigi2013/0002
31
+
32
+ # どんな言語なの?
33
+
34
+ - ErlangVM の上で動作する動的な関数型言語
35
+ - Elixirの特徴
36
+ - http://qiita.com/niku/items/7c61d6a6af38896ac603
37
+
38
+ # いいところ
39
+
40
+ | | 一般的 | + α がある |
41
+ | 特徴的 | | Lisp, Haskell, Erlang... |
42
+ | 親しみやすそう | 普段お使いの言語 | Elixir, Scala |
43
+
44
+ # Elixir
45
+
46
+ - (僕が) *したしみやすそう*
47
+ - 便利
48
+ - 道具が揃ってる :: *ErlangVM* や *Erlang* のライブラリを使える
49
+ - 構文を拡張しやすい :: *Lisp* みたいなマクロが書ける
50
+
51
+ # したしみ
52
+
53
+ - 構文
54
+ - ツール
55
+
56
+ # 構文
57
+
58
+ 1 + 1 # => 2
59
+ "abc" <> "def" # => "abcdef"
60
+ Enum.map([1, 2, 3], fn(x) -> x * 2 end) # => [2, 4, 6]
61
+
62
+ defmodule Greeting do
63
+ def hello(name) do
64
+ "hello " <> name
65
+ end
66
+ end
67
+
68
+ Greeting.hello("ニク") # => "hello ニク"
69
+ {: lang="ruby"}
70
+
71
+ # ツール
72
+
73
+ - ユニットテストツール *ExUnit*
74
+ - インタラクティブシェル *IEx*
75
+ - ビルドツール *Mix*
76
+ - パッケージ管理ツール *Hex*
77
+
78
+ # ためしてみよう
79
+
80
+
81
+
82
+ # プロジェクト作成
83
+
84
+ /Users/niku/projects% mix new exhomunculus
85
+ * creating README.md
86
+ * creating .gitignore
87
+ * creating mix.exs
88
+ * creating config
89
+ * creating config/config.exs
90
+ * creating lib
91
+ * creating lib/exhomunculus.ex
92
+ * creating test
93
+ * creating test/test_helper.exs
94
+ * creating test/exhomunculus_test.exs
95
+
96
+ Your mix project was created successfully.
97
+ You can use mix to compile it, test it, and more:
98
+
99
+ cd exhomunculus
100
+ mix test
101
+
102
+ Run `mix help` for more commands.
103
+
104
+ # テスト実行
105
+
106
+ /Users/niku/projects% cd exhomunculus
107
+ /Users/niku/projects/exhomunculus% mix test
108
+ Compiled lib/exhomunculus.ex
109
+ Generated exhomunculus.app
110
+ .
111
+
112
+ Finished in 0.1 seconds (0.1s on load, 0.01s on tests)
113
+ 1 tests, 0 failures
114
+
115
+ Randomized with seed 273204
116
+
117
+ # 挨拶を返す
118
+
119
+ 挨拶(greet)を命令すると "graaaa..." と返すようにしたい
120
+
121
+ # test/exhomunculus_test.exs
122
+ defmodule ExhomunculusTest do
123
+ use ExUnit.Case
124
+
125
+ test "the truth" do
126
+ assert 1 + 1 == 2
127
+ end
128
+
129
+ test "greet" do
130
+ assert Exhomunculus.greet == "graaaa..."
131
+ end
132
+ end
133
+ {: lang="ruby"}
134
+
135
+ # テスト実行
136
+
137
+ まだ作ってないので*失敗*する
138
+
139
+ /Users/niku/projects/exhomunculus% mix test
140
+
141
+
142
+ 1) test greet (ExhomunculusTest)
143
+ test/exhomunculus_test.exs:8
144
+ ** (UndefinedFunctionError) undefined function: Exhomunculus.greet/0
145
+ stacktrace:
146
+ (exhomunculus) Exhomunculus.greet()
147
+ test/exhomunculus_test.exs:9
148
+
149
+ .
150
+
151
+ Finished in 0.07 seconds (0.06s on load, 0.01s on tests)
152
+ 2 tests, 1 failures
153
+
154
+ Randomized with seed 848607
155
+
156
+ # プロダクションコード実装
157
+
158
+ # lib/exhomunculus.ex
159
+ defmodule Exhomunculus do
160
+ def greet do
161
+ "graaaa..."
162
+ end
163
+ end
164
+ {: lang="ruby"}
165
+
166
+ # テスト実行
167
+
168
+ /Users/niku/projects/exhomunculus% mix test
169
+ ..
170
+
171
+ Finished in 0.05 seconds (0.05s on load, 0.00s on tests)
172
+ 2 tests, 0 failures
173
+
174
+ Randomized with seed 150260
175
+
176
+ 通った.
177
+
178
+ *いつも通り*に開発できる.
179
+
180
+ # コマンドラインから使う
181
+
182
+ *escript* を使えばできる
183
+
184
+ /Users/niku/projects/exhomunculus% mix escript.build
185
+ Consolidated Access
186
+ Consolidated Collectable
187
+ Consolidated Enumerable
188
+ Consolidated Inspect
189
+ Consolidated List.Chars
190
+ Consolidated Range.Iterator
191
+ Consolidated String.Chars
192
+ Consolidated protocols written to _build/dev/consolidated
193
+ ** (Mix) Could not generate escript, please set :main_module \
194
+ in your project configuration (under `:escript` option) to a module that implements main/1
195
+
196
+ エラーが!
197
+
198
+ # エラーメッセージをよくみる
199
+
200
+ (Mix) Could not generate escript,
201
+
202
+ please set *:main_module* in your project configuration
203
+
204
+ (under *`:escript`* option) to a module
205
+
206
+ that *implements main/1*
207
+
208
+ # 必要なものを実装
209
+
210
+ エラーメッセージから
211
+
212
+ - *main* 関数がどのモジュールにあるかを *config で指定*する
213
+ - main/1 *関数名がmain*で*引数が1つ*の関数の用意をする
214
+
215
+ が必要だとわかる
216
+
217
+ # configで指定
218
+
219
+ # mix.exs
220
+ defmodule Exhomunculus.Mixfile do
221
+ use Mix.Project
222
+
223
+ def project do
224
+ [app: :exhomunculus,
225
+ version: "0.0.1",
226
+ elixir: "~> 1.0",
227
+ deps: deps,
228
+ escript: escript] # ここと
229
+ end
230
+
231
+ def application do
232
+ [applications: [:logger]]
233
+ end
234
+
235
+ defp deps do
236
+ []
237
+ end
238
+
239
+ def escript do
240
+ [main_module: Exhomunculus] # ここを追加
241
+ end
242
+ end
243
+ {: lang="ruby"}
244
+
245
+ # main/1 関数の用意
246
+
247
+ # lib/exhomunculus.ex
248
+ defmodule Exhomunculus do
249
+ def main(args) do # ここを追加
250
+ IO.puts greet #
251
+ end #
252
+
253
+ def greet do
254
+ "graaaa..."
255
+ end
256
+ end
257
+ {: lang="ruby"}
258
+
259
+ # 実行
260
+
261
+ /Users/niku/projects/exhomunculus% mix escript.build
262
+ lib/exhomunculus.ex:2: warning: variable args is unused
263
+ Compiled lib/exhomunculus.ex
264
+ Generated exhomunculus.app
265
+ Consolidated Access
266
+ Consolidated Collectable
267
+ Consolidated Enumerable
268
+ Consolidated Inspect
269
+ Consolidated List.Chars
270
+ Consolidated Range.Iterator
271
+ Consolidated String.Chars
272
+ Consolidated protocols written to _build/dev/consolidated
273
+ Generated escript exhomunculus with MIX_ENV=dev
274
+ /Users/niku/projects/exhomunculus% ./exhomunculus
275
+ graaaa...
276
+
277
+
278
+ # 天気情報を取得する
279
+
280
+ - HTTP経由でAPIから天気を取得
281
+ - http://weather.livedoor.com/weather_hacks/webservice
282
+
283
+ # 外部ライブラリの利用
284
+
285
+ - *HTTPアクセス* するのに *httpoison*
286
+ - https://github.com/edgurgel/httpoison
287
+ - *JSON解析* するのに *exjsx*
288
+ - https://github.com/talentdeficit/exjsx
289
+
290
+ # ライブラリの利用宣言
291
+
292
+ # mix.exs
293
+ defmodule Exhomunculus.Mixfile do
294
+ use Mix.Project
295
+
296
+ def project do
297
+ [app: :exhomunculus,
298
+ version: "0.0.1",
299
+ elixir: "~> 1.0",
300
+ deps: deps,
301
+ escript: escript]
302
+ end
303
+
304
+ def application do
305
+ [applications: [:logger, :httpoison]] # ここ
306
+ end
307
+
308
+ defp deps do
309
+ [httpoison: "~> 0.5", # ここ
310
+ exjsx: "~> 3.0"] #
311
+ end
312
+
313
+ def escript do
314
+ [main_module: Exhomunculus]
315
+ end
316
+ end
317
+ {: lang="ruby"}
318
+
319
+ # ライブラリのダウンロード
320
+
321
+ /Users/niku/projects/exhomunculus% mix deps.get
322
+
323
+ # インタラクティブシェル IEX
324
+
325
+ 動作を確認するのに使う
326
+
327
+ /Users/niku/projects/exhomunculus% iex -S mix
328
+ (...snip...)
329
+ iex(1)> "こんにちは"
330
+ "こんにちは"
331
+ iex(2)> [1, 2, 3]
332
+ [1, 2, 3]
333
+ iex(3)> "hi" <> "ho"
334
+ "hiho"
335
+ iex(4)> 1 + 2
336
+ 3
337
+ {: lang="irb"}
338
+
339
+ # ライブラリも試せる
340
+
341
+ /Users/niku/projects/exhomunculus% iex -S mix
342
+ iex(1)> url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=016010"
343
+ "http://weather.livedoor.com/forecast/webservice/json/v1?city=016010"
344
+ iex(2)> {:ok, %HTTPoison.Response{status_code: 200, body: body}} =
345
+ ...(2)> HTTPoison.get(url)
346
+ (...snip...)
347
+ iex(3)> json = JSX.decode! body
348
+ (...snip...)
349
+ iex(4)> json["description"]["text"]
350
+ " 北海道の西海上に低気圧があって、24日夜に北海道付近を通過し (略)"
351
+ {: lang="irb"}
352
+
353
+ # ここまで
354
+
355
+ *ふつう*です ^q^
356
+
357
+ # ここから
358
+
359
+ *ふつう*ではありません ^q^
360
+
361
+ # ErlangVM由来のふつうではないこと
362
+
363
+ - *プロセスをたくさん*つくれる
364
+ - *分散*させやすい
365
+ - *耐障害性*が高い
366
+
367
+ # プロセスをたくさんつくれる
368
+
369
+ https://gist.github.com/niku/7301933
370
+
371
+ # プロセスをたくさんつくれる
372
+
373
+ defmodule Chain do
374
+ def counter(next_pid) do
375
+ receive do
376
+ n ->
377
+ send next_pid, n + 1
378
+ end
379
+ end
380
+
381
+ def create_processes(n) do
382
+ last = Enum.reduce 1..n, self,
383
+ fn (_,send_to) ->
384
+ spawn(Chain, :counter, [send_to])
385
+ end
386
+
387
+ send last, 0
388
+
389
+ receive do
390
+ final_answer when is_integer(final_answer) ->
391
+ "Result is #{inspect(final_answer)}"
392
+ end
393
+ end
394
+
395
+ def run(n) do
396
+ IO.puts inspect :timer.tc(Chain, :create_processes, [n])
397
+ end
398
+ end
399
+ {: lang="ruby"}
400
+
401
+ # 同時に100万個生成
402
+
403
+ $ elixir --erl "+P 1000000" -r chain.exs -e "Chain.run(1_000_000)"
404
+ {9482041, "Result is 1000000"}
405
+
406
+ Macbook Proで9秒
407
+
408
+ # 分散させやすい
409
+
410
+ /Users/niku% mkdir a b
411
+ /Users/niku% cd a
412
+ /Users/niku/a% touch a.txt a.csv
413
+ /Users/niku/a% ls
414
+ a.csv a.txt
415
+ /Users/niku/a% iex --sname a
416
+ iex(a@niku-MacBook-Pro)1> node
417
+ :"a@niku-MacBook-Pro"
418
+ iex(a@niku-MacBook-Pro)2> File.ls
419
+ {:ok, ["a.csv", "a.txt"]}
420
+
421
+ ---------------------------------
422
+
423
+ /Users/niku% cd b
424
+ /Users/niku/b% touch b.txt
425
+ /Users/niku/b% ls
426
+ b.txt
427
+ /Users/niku/b% iex --sname b
428
+ iex(b@niku-MacBook-Pro)1> File.ls
429
+ {:ok, ["b.txt"]}
430
+ iex(b@niku-MacBook-Pro)2> Node.connect(:"a@niku-MacBook-Pro")
431
+ true
432
+ iex(b@niku-MacBook-Pro)3> current = self
433
+ #PID<0.59.0>
434
+ iex(b@niku-MacBook-Pro)4> Node.spawn(:"a@niku-MacBook-Pro",
435
+ fn -> send(current, File.ls) end)
436
+ #PID<9172.65.0>
437
+ iex(b@niku-MacBook-Pro)5> flush
438
+ {:ok, ["a.csv", "a.txt"]}
439
+
440
+ # 耐障害性が高い
441
+
442
+ (省略)
443
+
444
+ 力不足により簡単なサンプルを用意できませんでした
445
+
446
+ # Elixir独自のふつうではないこと
447
+
448
+ - マクロ!
449
+ - Elixirでメタプログラミングするのに使う
450
+
451
+ # マクロ?
452
+
453
+ 書いてあるコードを実行し始める前に書き換える
454
+
455
+ # どんなことができるの?
456
+
457
+ たとえば IF 式が作れます
458
+
459
+ # myif を作ってみる
460
+
461
+ if(評価) {
462
+ // 評価がtrueのときにやること
463
+ } else {
464
+ // 評価がfalseのときにやること
465
+ }
466
+ {: lang="javascript"}
467
+
468
+ # myif を作ってみる
469
+
470
+ - 評価対象(trueかfalseになる)
471
+ - true のときにやること
472
+ - false のときにやること
473
+
474
+ # JavaScriptでmyif
475
+
476
+ function myif(condition, iftrue, iffalse) {
477
+ return condition ? iftrue : iffalse;
478
+ }
479
+
480
+ console.log(myif(true, "_true", "_false")); // => _true
481
+ console.log(myif(false, "_true", "_false")); // => _false
482
+ {: lang="javascript"}
483
+
484
+ よさそう
485
+
486
+ # Javascriptでmyif
487
+
488
+ function myif(condition, iftrue, iffalse) {
489
+ return condition ? iftrue : iffalse;
490
+ }
491
+
492
+ myif(true, console.log("_true"), console.log("_false"));
493
+ {: lang="javascript"}
494
+
495
+ # Javascriptでmyif
496
+
497
+ function myif(condition, iftrue, iffalse) {
498
+ return condition ? iftrue : iffalse;
499
+ }
500
+
501
+ myif(true, console.log("_true"), console.log("_false"));
502
+ // => _true
503
+ // => _false
504
+ {: lang="javascript"}
505
+
506
+ あれ……
507
+
508
+ # Javascriptでmyif
509
+
510
+ function myif(condition, iftrue, iffalse) {
511
+ return condition ? iftrue : iffalse; // ←ここで評価してほしい
512
+ }
513
+
514
+ myif(true, console.log("_true"), console.log("_false")); // ここで評価してしまう
515
+ {: lang="javascript"}
516
+
517
+ myifの結果を返すときではなく,myifに引数を渡すときに評価されてしまう
518
+
519
+ # Javascriptでmyif
520
+
521
+ function myif(condition, iftrue, iffalse) {
522
+ return condition ? iftrue.call() : iffalse.call();
523
+ }
524
+
525
+ myif(true,
526
+ function() { return console.log("_true"); },
527
+ function() { return console.log("_false"); }); // => _true
528
+ myif(false,
529
+ function() { return console.log("_true"); },
530
+ function() { return console.log("_false"); }); // => _false
531
+ {: lang="javascript"}
532
+
533
+ 渡すときにfunctionにしておけば,結果を返すときに評価してくれる
534
+
535
+ # Javascriptでmyif
536
+
537
+ - 引数に渡すときのfunctionを無くすことはできないのか?
538
+ - =>引数に渡ってくる内容をfunctionとして,引数を受けとるときには評価しないようにできないの?
539
+ - JavaScriptでのやり方を知らない……
540
+
541
+ # 奥がふかいif
542
+
543
+ いつも使っているやつなのに,思ったよりたくさんの要素がある
544
+
545
+ # Elixirでmyif
546
+
547
+ - 関数でやると,JavaScriptと同じ悩みにあたる
548
+ - マクロ!
549
+
550
+ # Elixirでmyif
551
+
552
+ defmodule My do
553
+ defmacro my_if(clause, iftrue, iffalse) do
554
+ IO.inspect(clause)
555
+ IO.inspect(iftrue)
556
+ IO.inspect(iffalse)
557
+ end
558
+ end
559
+
560
+ defmodule MyTest do
561
+ def run do
562
+ import My
563
+ My.my_if(true) do
564
+ IO.inspect("_true")
565
+ else
566
+ IO.inspect("_false")
567
+ end
568
+ end
569
+ end
570
+
571
+ MyTest.run
572
+ {: lang="ruby"}
573
+
574
+ # Elixirでmyif
575
+
576
+ 実行結果
577
+
578
+ true # => IO.inspect(clause) 分
579
+ {{:., [line: 12], [{:__aliases__, [counter: 0, line: 12], [:IO]}, :inspect]},
580
+ [line: 12], ["_true"]} # => IO.inspect(iftrue) 分
581
+ {{:., [line: 12], [{:__aliases__, [counter: 0, line: 12], [:IO]}, :inspect]},
582
+ [line: 12], ["_false"]} # => IO.inspect(iffalse) 分
583
+ "_false"
584
+ {: lang="ruby"}
585
+
586
+ なんだこれは……
587
+
588
+ # Elixirでmyif
589
+
590
+ http://elixir-lang.org/getting_started/meta/1.html
591
+
592
+ Elixir の文献によると
593
+
594
+ { tuple か atom, list, list か atom }
595
+
596
+ 3要素のくみあわせになっている
597
+
598
+ # Elixirでmyif
599
+
600
+ - 一番目の要素はアトムかタプル.タプルの場合はこの構造と同じになっている
601
+ - 二番目の要素はメタデータ.行数とか文脈が書いてある.
602
+ - 三番目の要素はアトムか関数呼び出しの引数.アトムの場合,このひとかたまりタプルは変数である.
603
+
604
+ # Elixirでmyif
605
+
606
+ IO.inspect(clause)のなかみ
607
+
608
+ {{:., [line: 12], [{:__aliases__, [counter: 0, line: 12], [:IO]}, :inspect]},
609
+ [line: 12], ["_true"]}
610
+
611
+ {{tuple},
612
+ [list], [list]}
613
+ {: lang="ruby"}
614
+
615
+ # Elixirでmyif
616
+
617
+ 1 番目のタプルのなかみ
618
+
619
+ {:., [line: 12], [{:__aliases__, [counter: 0, line: 12], [:IO]}, :inspect]},
620
+
621
+ {:atom, [list], [list]}
622
+ {: lang="ruby"}
623
+
624
+ # Elixirでmyif
625
+
626
+ - 以下略.たしかにそのようになっているようだ.
627
+ - これなんなの? => AST(抽象構文木)です
628
+ - ASTってなんなの?プログラムの構造をプログラムで表したものです
629
+
630
+ # Elixirでmyif
631
+
632
+ とりあえず忘れてください.IO.inspect の*出力が最後に出てくる*ことに注目
633
+
634
+ true
635
+ {{:., [line: 12], [{:__aliases__, [counter: 0, line: 12], [:IO]}, :inspect]},
636
+ [line: 12], ["_true"]}
637
+ {{:., [line: 12], [{:__aliases__, [counter: 0, line: 12], [:IO]}, :inspect]},
638
+ [line: 12], ["_false"]}
639
+ "_false" # <= **ココ**
640
+ {: lang="ruby"}
641
+
642
+ # Elixirでmyif
643
+
644
+ - IO.inspect の出力が最後に出てくる
645
+ - つまり引数で受けたときにはまだ評価されていない
646
+
647
+ # Elxiirでmyif
648
+
649
+ defmodule My do
650
+ defmacro my_if(clause, iftrue, iffalse) do
651
+ quote do
652
+ case unquote(clause) do
653
+ false -> unquote(iffalse)
654
+ nil -> unquote(iffalse)
655
+ _ -> unquote(iftrue)
656
+ end
657
+ end
658
+ end
659
+ end
660
+
661
+ defmodule MyTest do
662
+ def run do
663
+ import My
664
+ My.my_if(true, IO.inspect("_true"), IO.inspect("_false"))
665
+ My.my_if(false, IO.inspect("_true"), IO.inspect("_false"))
666
+ My.my_if(nil, IO.inspect("_true"), IO.inspect("_false"))
667
+ end
668
+ end
669
+
670
+ MyTest.run
671
+ "_true"
672
+ "_false"
673
+ "_false"
674
+ {: lang="ruby"}
675
+
676
+ # Elxiirでmyif
677
+
678
+ - できた
679
+ - マクロは慣れていない人類には早すぎる感
680
+
681
+ # Elixirでmyif
682
+
683
+ > Never use a macro when you can use a function
684
+ >
685
+ > -- Programming Elixir
686
+
687
+ # まとめ
688
+
689
+ - ライブラリを使う人には現代的でしたしみやすい
690
+ - ライブラリを作る人にはほとんどなんでもできる
691
+
692
+ # 宣伝
693
+
694
+ - 毎週だいたい木曜日にErlangVMに関すること(Elixir含む)や,そうではないことをワイワイやるSapporo.beamをやってます
695
+ - 前回は高級トイレットペーパーのはなしやこの資料の作成をしてました
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rabbit-slide-niku-techmix-hokkaido-2014-elixir
3
+ version: !ruby/object:Gem::Version
4
+ version: 2014.12.06
5
+ platform: ruby
6
+ authors:
7
+ - niku
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-06 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: "[Techmix Hokkaido 2014](http://www.techmix-hokkaido.com/) の発表に用いた資料です"
28
+ email:
29
+ - niku@niku.name
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".rabbit"
35
+ - README.md
36
+ - Rakefile
37
+ - config.yaml
38
+ - pdf/techmix-hokkaido-2014-elixir-techmix-hokkaido-2014-elixir.pdf
39
+ - techmix-hokkaido-2014-elixir.md
40
+ homepage: http://slide.rabbit-shocker.org/authors/niku/techmix-hokkaido-2014-elixir/
41
+ licenses: []
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.2.2
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Techmix Hokkaido 2014 Elixir
63
+ test_files: []