ヽ(´・肉・`)ノログ

How do we fighting without fighting?

すごいE本をElixirでやる(7)

つづき

1 章

1.3 バイナリデータを扱う

ビット単位のバイナリ操作

Elixir でのバイナリ演算は Bitwise が担っている.

Eshell V6.1  (abort with ^G)
Interactive Elixir (0.15.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> use Bitwise
nil
iex(2)> 0b00100 = bsl 0b0010, 1
4
iex(3)> 0b00001 = bsr 0b0010, 1
1
iex(4)> 0b10101 = bor 0b10001, 0b00101
21

バイナリ文字列

リストと比べてバイナリ文字列の不利な点は、パターンマッチや操作の際の単純さが失われることです

と書いてあるけど,Erlang でバイナリ文字操作するのは面倒なのかなあ.Elixir はバイナリ文字列操作を特に苦手にしていないように見える.

String を眺めると色々できることがわかる.

バイナリ内包表記

Elixir でのバイナリ内包表記は 18.2 Bitstring generators を見ると概要がわかる.

より詳しくは Kernel.SpecialForms.for/1 を見るとよい.( 僕は into についてここで知った )

1 行目のように バイナリ内包表記の中でバイナリを扱うときに

for <<x <- <<1,2,3,4,5>>>>, rem(x, 2) === 0, do: x

>>>> を繋げて書いてしまうと,パーサーが上手く文を区切ってくれないので必ずスペースを開けなければならない.

あと Elixir の内包表記は何も指定しないと常にリストが返るので,バイナリを返したいときには into を指定すること.

上に挙げた Kernel.SpecialForms.for/1 に書いてある.

Eshell V6.1  (abort with ^G)
Interactive Elixir (0.15.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> for <<x <- <<1,2,3,4,5>> >>, rem(x, 2) === 0, do: x
[2, 4]
iex(2)> pixels = <<213, 45, 132, 64, 76, 32, 76, 0, 0, 234, 32, 15>>
<<213, 45, 132, 64, 76, 32, 76, 0, 0, 234, 32, 15>>
iex(3)> rgb = for <<r::8, g::8, b::8 <- pixels >>, do: {r, g, b}
[{213, 45, 132}, {64, 76, 32}, {76, 0, 0}, {234, 32, 15}]
iex(4)> for {r, g, b} <- rgb, into: "", do: <<r::8, g::8, b::8>>
<<213, 45, 132, 64, 76, 32, 76, 0, 0, 234, 32, 15>>
iex(5)> for bin <- [<<3, 7, 5, 4, 7>>], into: "", do: <<bin>>
** (ArgumentError) argument error

iex(5)> for bin <- [<<3, 7, 5, 4, 7>>], into: "", do: <<bin::binary>>
<<3, 7, 5, 4, 7>>
iex(6)> for << x <- <<3, 7, 5, 4, 7>> >>, into: "", do: <<x+1::integer>>
<<4, 8, 6, 5, 8>>
このエントリーをはてなブックマークに追加