rabbit-slide-niku-introduction-of-elixir-at-rubysapporo-28 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rabbit +1 -0
- data/README.md +23 -0
- data/Rakefile +9 -0
- data/config.yaml +19 -0
- data/introduction-of-elixir-at-rubysapporo-28.md +374 -0
- data/pdf/introduction-of-elixir-at-rubysapporo-28-introducition-of-elixir-at-rubysapporo-28.pdf +0 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8e7bc0387298e9678d235d600e3d6ca2909b9d2d
|
4
|
+
data.tar.gz: b610146b66202928c04aaa5982073940b8f4cfc3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ff362952edfdc83d4b0f44b8500b460ce969382297f98c8b19892c9bcc7a185049b80b87ff78e542ade1a9a8a4325d712105993a82608a6c437dd04ef4012f52
|
7
|
+
data.tar.gz: a1f595620ea0cb91183860395634836e4f94d8460c40db24ce3e7bcea42b48088c0ed57330a71b431c9405430b3f9a9b4b4bb217146087b8fceb30b8318e92c1
|
data/.rabbit
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
introduction-of-elixir-at-rubysapporo-28.md
|
data/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Elixir 触ってみた @ Ruby 札幌 28
|
2
|
+
|
3
|
+
[Ruby勉強会@札幌-28](http://ruby-sapporo.org/news/2013/10/18/workshop-28.html) で発表した [elixir-lang](http://elixir-lang.org/) の資料です.
|
4
|
+
|
5
|
+
## 作者向け
|
6
|
+
|
7
|
+
### 表示
|
8
|
+
|
9
|
+
rake
|
10
|
+
|
11
|
+
### 公開
|
12
|
+
|
13
|
+
rake publish
|
14
|
+
|
15
|
+
## 閲覧者向け
|
16
|
+
|
17
|
+
### インストール
|
18
|
+
|
19
|
+
gem install rabbit-slide-niku-introduction-of-the-elixir-lang-at-ruby-sapporo-28
|
20
|
+
|
21
|
+
### 表示
|
22
|
+
|
23
|
+
rabbit rabbit-slide-niku-introduction-of-the-elixir-lang-at-ruby-sapporo-28.gem
|
data/Rakefile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require "rabbit/task/slide"
|
2
|
+
|
3
|
+
# Edit ./config.yaml to customize meta data
|
4
|
+
|
5
|
+
Rabbit::Task::Slide.new do |task|
|
6
|
+
# task.spec.files += Dir.glob("doc/**/*.*")
|
7
|
+
# task.spec.files -= Dir.glob("private/**/*.*")
|
8
|
+
# task.spec.add_runtime_dependency("YOUR THEME")
|
9
|
+
end
|
data/config.yaml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
id: introduction-of-elixir-at-rubysapporo-28
|
3
|
+
base_name: introducition-of-elixir-at-rubysapporo-28
|
4
|
+
tags:
|
5
|
+
- elixir-lang
|
6
|
+
presentation_date:
|
7
|
+
version: 1.0.0
|
8
|
+
licenses: []
|
9
|
+
slideshare_id:
|
10
|
+
speaker_deck_id:
|
11
|
+
ustream_id:
|
12
|
+
vimeo_id:
|
13
|
+
author:
|
14
|
+
markup_language: :markdown
|
15
|
+
name: niku
|
16
|
+
email: niku@niku.name
|
17
|
+
rubygems_user: niku
|
18
|
+
slideshare_user:
|
19
|
+
speaker_deck_user: niku
|
@@ -0,0 +1,374 @@
|
|
1
|
+
# Elixir 触ってみた @ Ruby札幌28
|
2
|
+
|
3
|
+
author
|
4
|
+
: ヽ(´・肉・`)ノ
|
5
|
+
|
6
|
+
# 本人いわく
|
7
|
+
|
8
|
+
<http://elixir-lang.org/>
|
9
|
+
に書いてある Elixir による自己紹介
|
10
|
+
|
11
|
+
# 全部が式
|
12
|
+
|
13
|
+
iex(1)> defmodule Hello do
|
14
|
+
...(1)> IO.puts "Defining the function world"
|
15
|
+
...(1)>
|
16
|
+
...(1)> def world do
|
17
|
+
...(1)> IO.puts "Hello World"
|
18
|
+
...(1)> end
|
19
|
+
...(1)>
|
20
|
+
...(1)> IO.puts "Function world defined"
|
21
|
+
...(1)> end
|
22
|
+
Defining the function world
|
23
|
+
Function world defined
|
24
|
+
iex(2)> Hello.world
|
25
|
+
Hello World
|
26
|
+
:ok
|
27
|
+
|
28
|
+
# 全部が式(2)
|
29
|
+
|
30
|
+
- module は沢山の式からなりたっている.
|
31
|
+
- module の内容をプログラムで書ける
|
32
|
+
|
33
|
+
メタプログラミングできる
|
34
|
+
|
35
|
+
# メタプログラミングとDSL
|
36
|
+
|
37
|
+
DSL を簡単に作れる(ExUnitの例)
|
38
|
+
|
39
|
+
defmodule MathTest do
|
40
|
+
use ExUnit.Case
|
41
|
+
|
42
|
+
test "can add two numbers" do
|
43
|
+
assert 1 + 1 == 2
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# protocol によるポリモーフィズム
|
48
|
+
|
49
|
+
ファイルにも配列にも使えるEnumモジュール
|
50
|
+
|
51
|
+
Enum.map([1,2,3], fn(x) -> x * 2 end) #=> [2,4,6]
|
52
|
+
|
53
|
+
# ----
|
54
|
+
|
55
|
+
file = File.stream!("README.md")
|
56
|
+
lines = Enum.map(file, fn(line) -> Regex.replace(%r/"/, line, "'") end)
|
57
|
+
File.write("README.md", lines)
|
58
|
+
|
59
|
+
# protocol によるポリモーフィズム(2)
|
60
|
+
|
61
|
+
- 自作モジュールでも Enum を使いたい
|
62
|
+
- Enum は Enumerable という protocol があれば使える
|
63
|
+
- MyModule 向けに Enumerable を実装する
|
64
|
+
|
65
|
+
# protocol によるポリモーフィズム(3)
|
66
|
+
|
67
|
+
defimpl Enumerable, for: MyModule do
|
68
|
+
def reduce(collection, acc, fun), do
|
69
|
+
# (....)
|
70
|
+
end
|
71
|
+
|
72
|
+
def member?(collection, value), do
|
73
|
+
# (....)
|
74
|
+
end
|
75
|
+
|
76
|
+
def count(collection), do
|
77
|
+
# (....)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# 一級市民としてのドキュメント
|
82
|
+
|
83
|
+
- 言語レベルでドキュメント化をサポートしている.
|
84
|
+
- 色んなツールで簡単にドキュメントを使える.
|
85
|
+
- マークアップ記法として Markdown を使える.
|
86
|
+
|
87
|
+
# 一級市民としてのドキュメント(2)
|
88
|
+
|
89
|
+
defmodule MyModule do
|
90
|
+
@moduledoc """
|
91
|
+
Documentation for my module. With **formatting**.
|
92
|
+
"""
|
93
|
+
|
94
|
+
@doc "Hello"
|
95
|
+
def world do
|
96
|
+
"World"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# 一級市民としてのドキュメント(3)
|
101
|
+
|
102
|
+
$ iex -r my_module.exs
|
103
|
+
iex(1)> h MyModule
|
104
|
+
# MyModule
|
105
|
+
|
106
|
+
Documentation for my module. With **formatting**.
|
107
|
+
iex(2)> h MyModule.world
|
108
|
+
* def world()
|
109
|
+
|
110
|
+
Hello
|
111
|
+
|
112
|
+
# パターンマッチング
|
113
|
+
|
114
|
+
まとまっているものをバラバラにして扱いやすくする
|
115
|
+
|
116
|
+
iex(1)> u = { :user, "John Doe", 19 }
|
117
|
+
{:user, "John Doe", 19}
|
118
|
+
iex(2)> elem u, 1
|
119
|
+
"John Doe"
|
120
|
+
iex(3)> { type, name ,age } = { :user, "John Doe", 19 }
|
121
|
+
{:user, "John Doe", 19}
|
122
|
+
iex(4)> type
|
123
|
+
:user
|
124
|
+
iex(5)> name
|
125
|
+
"John Doe"
|
126
|
+
iex(6)> age
|
127
|
+
19
|
128
|
+
|
129
|
+
# パターンマッチング(2)
|
130
|
+
|
131
|
+
ガード節 (when) と混ぜると意図が伝わりやすくなる
|
132
|
+
|
133
|
+
def serve_drinks({ User, name, age }) when age < 20 do
|
134
|
+
raise "No way #{name}!"
|
135
|
+
end
|
136
|
+
|
137
|
+
def serve_drinks({ User, name, age }) do
|
138
|
+
# Code that serves drinks!
|
139
|
+
end
|
140
|
+
|
141
|
+
# ----
|
142
|
+
|
143
|
+
serve_drinks User.get("John")
|
144
|
+
#=> Raises "No way John!" if John is under 20
|
145
|
+
|
146
|
+
# 隅から隅まで Erlang
|
147
|
+
|
148
|
+
:application.start(:crypto)
|
149
|
+
:crypto.md5("Using crypto from Erlang OTP")
|
150
|
+
#=> <<192,223,75,115,...>>
|
151
|
+
|
152
|
+
- バイトコードレベルで互換
|
153
|
+
- 変換が容易
|
154
|
+
- Elixir から Erlang の関数はコスト 0 で実行できる
|
155
|
+
|
156
|
+
# 本人いわく,のまとめ
|
157
|
+
|
158
|
+
- 全部が式
|
159
|
+
- メタプログラミングとDSL
|
160
|
+
- protocol によるポリモーフィズム
|
161
|
+
- 一級市民としてのドキュメント
|
162
|
+
- パターンマッチ
|
163
|
+
- 隅から隅まで Erlang
|
164
|
+
|
165
|
+
# 触ってみたくなった?
|
166
|
+
|
167
|
+
インストール方法は
|
168
|
+
<http://elixir-lang.org/getting_started/1.html>
|
169
|
+
の 1.1 Installation に書いてある.
|
170
|
+
|
171
|
+
- Erlang R16B 以降
|
172
|
+
- Elixir
|
173
|
+
|
174
|
+
が必要.
|
175
|
+
|
176
|
+
# 触ってみたくなった?(Mac)
|
177
|
+
|
178
|
+
brew install elixir
|
179
|
+
|
180
|
+
で両方インストールできる.
|
181
|
+
|
182
|
+
# 触ってみたくなった?(Windows)
|
183
|
+
|
184
|
+
- Erlang: <http://www.erlang.org/download.html>
|
185
|
+
- Elixir: <https://github.com/elixir-lang/elixir/releases/>
|
186
|
+
|
187
|
+
それぞれのコンパイル済 zip をダウンロードして解凍して使うのが簡単でおすすめ ( らしい )
|
188
|
+
|
189
|
+
# モダンなプログラミング言語
|
190
|
+
|
191
|
+
最近のプログラミング言語が備えている特徴
|
192
|
+
Elixir も備えている
|
193
|
+
|
194
|
+
# パッケージ管理
|
195
|
+
|
196
|
+
mix :: Ruby の Rake と Bundler を合わせたようなもの
|
197
|
+
|
198
|
+
- mix new: プロジェクトを作る
|
199
|
+
- mix test: テストを実行する
|
200
|
+
- mix compile: コンパイルする
|
201
|
+
|
202
|
+
mix --help で詳しくみられる
|
203
|
+
|
204
|
+
# ライブラリ管理 (みあたらず)
|
205
|
+
|
206
|
+
- rubygems を操作する gem のようなコマンドはまだ見つけられない
|
207
|
+
- rubygems 相当のライブラリ置き場は <http://expm.co> というのがある
|
208
|
+
|
209
|
+
# REPL
|
210
|
+
|
211
|
+
iex :: Ruby の irb のようなもの
|
212
|
+
|
213
|
+
iex(1)> "ほげほげ"
|
214
|
+
"ほげほげ"
|
215
|
+
iex(2)> 1 + 1
|
216
|
+
2
|
217
|
+
iex(3)> def foo do
|
218
|
+
...(3)> "foo"
|
219
|
+
...(3)> end
|
220
|
+
** (SyntaxError) iex:3: cannot invoke def outside module
|
221
|
+
src/elixir_macros.erl:184: :elixir_macros.translate/2
|
222
|
+
lists.erl:1339: :lists.mapfoldl/3
|
223
|
+
src/elixir.erl:134: :elixir.eval_forms/3
|
224
|
+
iex(3)> defmodule Foo do
|
225
|
+
...(3)> def bar do
|
226
|
+
...(3)> "bar"
|
227
|
+
...(3)> end
|
228
|
+
...(3)> end
|
229
|
+
iex(4)> Foo.bar
|
230
|
+
"bar"
|
231
|
+
|
232
|
+
# ユニットテスト
|
233
|
+
|
234
|
+
ExUnit :: Ruby の Test::Unit みたいなもの
|
235
|
+
|
236
|
+
defmodule MathTest do
|
237
|
+
use ExUnit.Case
|
238
|
+
|
239
|
+
test "can add two numbers" do
|
240
|
+
assert 1 + 1 == 2
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# モダンなプログラミング環境のまとめ
|
245
|
+
|
246
|
+
- パッケージ管理
|
247
|
+
- ライブラリ管理(みあたらず)
|
248
|
+
- REPL
|
249
|
+
- ユニットテスト
|
250
|
+
|
251
|
+
# Elixir らしそうなところ
|
252
|
+
|
253
|
+
個人的におおっ!
|
254
|
+
となったところ
|
255
|
+
|
256
|
+
# マクロ
|
257
|
+
|
258
|
+
Elixir の内容は全て 3 要素のタプルで表されている
|
259
|
+
|
260
|
+
- atom か,同じ形式のタプル
|
261
|
+
- メタデータのリスト.ノードの番号とか行番号などを保持する
|
262
|
+
- 呼び出す関数の引数のリストか atom
|
263
|
+
|
264
|
+
ほとんどの構文がマクロで作られている
|
265
|
+
|
266
|
+
# マクロ(2)
|
267
|
+
|
268
|
+
iex(1)> 1 + 2
|
269
|
+
3
|
270
|
+
iex(2)> quote do: 1 + 2
|
271
|
+
{:+, [context: Elixir, import: Kernel], [1, 2]}
|
272
|
+
iex(3)> defmodule MyMacro do
|
273
|
+
...(3)> defmacro one_plus_two do
|
274
|
+
...(3)> {:+, [], [1,2]}
|
275
|
+
...(3)> end
|
276
|
+
...(3)> end
|
277
|
+
iex(4)> require MyMacro
|
278
|
+
nil
|
279
|
+
iex(5)> MyMacro.one_plus_two
|
280
|
+
3
|
281
|
+
|
282
|
+
# マクロ(3)
|
283
|
+
|
284
|
+
iex(1)> defmodule MyMacro do
|
285
|
+
...(1)> defmacro unless(clause, options) do
|
286
|
+
...(1)> quote do: if(!unquote(clause), unquote(options))
|
287
|
+
...(1)> end
|
288
|
+
...(1)> end
|
289
|
+
iex(2)>
|
290
|
+
nil
|
291
|
+
iex(3)> require MyMacro
|
292
|
+
nil
|
293
|
+
iex(4)> MyMacro.unless true, do: IO.puts "false"
|
294
|
+
nil
|
295
|
+
iex(5)> MyMacro.unless false, do: IO.puts "false"
|
296
|
+
false
|
297
|
+
:ok
|
298
|
+
|
299
|
+
# 並列
|
300
|
+
|
301
|
+
並列があたりまえ.
|
302
|
+
簡単に作れるようになっている.
|
303
|
+
|
304
|
+
- spawn : 違うプロセスを作る
|
305
|
+
- x <- y : プロセス x に y という内容を送る
|
306
|
+
- receive : 送られた内容を取得する
|
307
|
+
|
308
|
+
# 並列(2)
|
309
|
+
|
310
|
+
iex(1)> current_pid = self
|
311
|
+
#PID<0.26.0>
|
312
|
+
iex(2)> spawn fn ->
|
313
|
+
...(2)> current_pid <- { :hello, self }
|
314
|
+
...(2)> end
|
315
|
+
#PID<0.40.0>
|
316
|
+
iex(3)> receive do
|
317
|
+
...(3)> { :hello, pid } ->
|
318
|
+
...(3)> IO.puts "Hello from #{inspect(pid)}"
|
319
|
+
...(3)> end
|
320
|
+
Hello from #PID<0.40.0>
|
321
|
+
:ok
|
322
|
+
|
323
|
+
# 並列(3)
|
324
|
+
|
325
|
+
<https://gist.github.com/niku/7301933>
|
326
|
+
|
327
|
+
普通の MacBook で 100 万プロセス生成 16 秒で動くんだぜー
|
328
|
+
|
329
|
+
$ elixir --erl "+P 1000000" -r chain.exs -e "Chain.run(1_000_000)"
|
330
|
+
{16961375, "Result is 1000000"}
|
331
|
+
|
332
|
+
# OTP
|
333
|
+
|
334
|
+
OTPとは何か?
|
335
|
+
|
336
|
+
<http://www.ymotongpoo.com/works/lyse-ja/ja/16_what_is_otp.html>
|
337
|
+
|
338
|
+
- 大抵のプロセスでは,共通の処理がある
|
339
|
+
- パターンを見極めて,共通ライブラリにまとめたもの
|
340
|
+
|
341
|
+
# OTP(2)
|
342
|
+
|
343
|
+
OTP の便利なところ(一部)
|
344
|
+
|
345
|
+
- ワーカープロセスの監視/再起動が **組み込まれている**
|
346
|
+
- ダウンタイム **ゼロ** のリリース,デプロイ
|
347
|
+
|
348
|
+
# Elixir らしそうなところのまとめ
|
349
|
+
|
350
|
+
- マクロ (Elixirすごい)
|
351
|
+
- 並列 (Elixirが使っているErlangVMすごい)
|
352
|
+
- OTP (Elixirが使っているErlangのライブラリすごい)
|
353
|
+
|
354
|
+
# 思考の転換
|
355
|
+
|
356
|
+
> プログラマの思考はプログラミング言語に影響される
|
357
|
+
|
358
|
+
<http://gihyo.jp/news/report/01/rubykaigi2013/0001>
|
359
|
+
|
360
|
+
"まつもとゆきひろさん,Rubyに影響を与えた言語とRuby開発初期を語る。 ~ RubyKaigi 2013 基調講演 1日目"
|
361
|
+
|
362
|
+
# 想像してみてほしい
|
363
|
+
|
364
|
+
- もし並列処理が簡単に書けるなら
|
365
|
+
- もし無制限に並列処理できるなら
|
366
|
+
|
367
|
+
どんな考え方をするだろう?
|
368
|
+
Elixir を使って試してみようぜ.
|
369
|
+
|
370
|
+
# 参考にしている本/サイト
|
371
|
+
|
372
|
+
- <http://elixir-lang.org/getting_started/>
|
373
|
+
- <http://www.ymotongpoo.com/works/lyse-ja/index.html>
|
374
|
+
- <http://pragprog.com/book/elixir/programming-elixir>
|
data/pdf/introduction-of-elixir-at-rubysapporo-28-introducition-of-elixir-at-rubysapporo-28.pdf
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rabbit-slide-niku-introduction-of-elixir-at-rubysapporo-28
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- niku
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-04 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: |
|
28
|
+
[Ruby勉強会@札幌-28](http://ruby-sapporo.org/news/2013/10/18/workshop-28.html) で発表した [elixir-lang](http://elixir-lang.org/) の資料です.
|
29
|
+
|
30
|
+
## 作者向け
|
31
|
+
|
32
|
+
### 表示
|
33
|
+
|
34
|
+
rake
|
35
|
+
|
36
|
+
### 公開
|
37
|
+
|
38
|
+
rake publish
|
39
|
+
|
40
|
+
## 閲覧者向け
|
41
|
+
|
42
|
+
### インストール
|
43
|
+
|
44
|
+
gem install rabbit-slide-niku-introduction-of-the-elixir-lang-at-ruby-sapporo-28
|
45
|
+
|
46
|
+
### 表示
|
47
|
+
|
48
|
+
rabbit rabbit-slide-niku-introduction-of-the-elixir-lang-at-ruby-sapporo-28.gem
|
49
|
+
email:
|
50
|
+
- niku@niku.name
|
51
|
+
executables: []
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- .rabbit
|
56
|
+
- config.yaml
|
57
|
+
- Rakefile
|
58
|
+
- README.md
|
59
|
+
- introduction-of-elixir-at-rubysapporo-28.md
|
60
|
+
- pdf/introduction-of-elixir-at-rubysapporo-28-introducition-of-elixir-at-rubysapporo-28.pdf
|
61
|
+
homepage: http://slide.rabbit-shocker.org/authors/niku/introduction-of-elixir-at-rubysapporo-28/
|
62
|
+
licenses: []
|
63
|
+
metadata: {}
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.0.3
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: '# Elixir 触ってみた @ Ruby 札幌 28'
|
84
|
+
test_files: []
|