LoginSignup
4
0

More than 5 years have passed since last update.

ZEAM開発ログ v.0.4.5 ビット列について調べてみる

Last updated at Posted at 2018-09-22

ZACKY こと山崎進です。

今回は少し脱線して,Elixir のビット列について調べてみます。将来C言語との特に構造体によるインタフェースを考える上で重要になってきます。

ところで 菊池 豊さん @kikuyuta の記事を書くペースが半端ないですね! 今回の記事でささやかながら対抗してみたいと思いますw

「ZEAM開発ログ 目次」はこちら

さっそく iex の実行結果を見てみましょう

$ iex
Erlang/OTP 21 [erts-10.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> bs = << 3 :: size(2) >>
<<3::size(2)>>
iex(2)> is_bitstring(bs)
true
iex(3)> is_binary(bs) 
false
iex(4)> byte_size(bs)
1
iex(5)> bs = << 0 :: size(2), 1 :: size(2), 2 :: size(2), 3 :: size(2)>>
"\e"
iex(6)> is_bitstring(bs)
true
iex(7)> is_binary(bs)
true
iex(8)> byte_size(bs)
1
iex(9)> << head :: size(2), tail :: bitstring >> = bs
"\e"
iex(10)> head
0
iex(11)> tail
<<27::size(6)>>
iex(12)> << head :: size(2), tail :: bitstring >> = tail
<<27::size(6)>>
iex(13)> head                                           
1
iex(14)> tail                                           
<<11::size(4)>>
iex(15)> << head :: size(2), tail :: bitstring >> = tail
<<11::size(4)>>
iex(16)> head                                           
2
iex(17)> tail                                           
<<3::size(2)>>
iex(18)> << head :: size(2), tail :: bitstring >> = tail
<<3::size(2)>>
iex(19)> head                                           
3
iex(20)> tail                                           
""
iex(21)> << head :: size(2), tail :: bitstring >> = tail
** (MatchError) no match of right hand side value: ""
    (stdlib) erl_eval.erl:450: :erl_eval.expr/5
    (iex) lib/iex/evaluator.ex:250: IEx.Evaluator.handle_eval/5
    (iex) lib/iex/evaluator.ex:230: IEx.Evaluator.do_eval/3
    (iex) lib/iex/evaluator.ex:208: IEx.Evaluator.eval/3
    (iex) lib/iex/evaluator.ex:94: IEx.Evaluator.loop/1
    (iex) lib/iex/evaluator.ex:24: IEx.Evaluator.init/4

何をしたか解説します。

iex(1)> bs = << 3 :: size(2) >>
<<3::size(2)>>

10進数で3,2進数で11の値を持つ2ビット列 bs を定義してみました。

iex(2)> is_bitstring(bs)
true
iex(3)> is_binary(bs) 
false
iex(4)> byte_size(bs)
1

ビット列は is_bitstringtrueis_binaryfalse になります。byte_size は1バイトです。

iex(5)> bs = << 0 :: size(2), 1 :: size(2), 2 :: size(2), 3 :: size(2)>>
"\e"

それぞれ 0, 1, 2, 3 の2ビットの値を4つ持つビット列 bs を定義してみました。2進数で 00011011,16進数で1bですから,UTF-8 で ESC "\e" になります。

iex(6)> is_bitstring(bs)
true
iex(7)> is_binary(bs)
true
iex(8)> byte_size(bs)
1

8ビット充足すると is_binary も true になります。


iex(9)> << head :: size(2), tail :: bitstring >> = bs
"\e"
iex(10)> head
0
iex(11)> tail
<<27::size(6)>>

ビット列もリストのように headtail に分解できます。これはなかなか強力な操作です。

iex(12)> << head :: size(2), tail :: bitstring >> = tail
<<27::size(6)>>
iex(13)> head                                           
1
iex(14)> tail                                           
<<11::size(4)>>
iex(15)> << head :: size(2), tail :: bitstring >> = tail
<<11::size(4)>>
iex(16)> head                                           
2
iex(17)> tail                                           
<<3::size(2)>>
iex(18)> << head :: size(2), tail :: bitstring >> = tail
<<3::size(2)>>
iex(19)> head                                           
3
iex(20)> tail                                           
""

空になるまで分解してみました。

iex(20)> tail                                           
""
iex(21)> << head :: size(2), tail :: bitstring >> = tail
** (MatchError) no match of right hand side value: ""
    (stdlib) erl_eval.erl:450: :erl_eval.expr/5
    (iex) lib/iex/evaluator.ex:250: IEx.Evaluator.handle_eval/5
    (iex) lib/iex/evaluator.ex:230: IEx.Evaluator.do_eval/3
    (iex) lib/iex/evaluator.ex:208: IEx.Evaluator.eval/3
    (iex) lib/iex/evaluator.ex:94: IEx.Evaluator.loop/1
    (iex) lib/iex/evaluator.ex:24: IEx.Evaluator.init/4

空になってなおパターンマッチしようとすると MatchError になります。

次回ですが, @Tsuyoshi84 さんが素敵な記事「OKを使ってElixirの :ok, :error タプルをエレガントに処理」を書いてくれたので,それに刺激を受けて「ZEAM開発ログ v.0.4.6 OKを使ってNIFのエラー処理をエレガントに書いてみる」をお送りします。お楽しみに!

:stars::stars::stars: お知らせ:Elixirもくもく会(リモート参加OK、入門トラック有)を9月28日に開催します :stars::stars::stars:

「fukuoka.ex#14:Elixir/Phoenixもくもく会~入門もあるよ」を2018年9月28日金曜日に開催します

前回は,ゲリラ的に募った「Zoomによるリモート参加」を,今回から正式に受け付けるようになりましたので,福岡以外の首都圏や地方からでも参加できます(申し込みいただいたら、追ってZoom URLをconnpassメールでお送りします)

また,これまではElixir/Phoenix経験者を対象とした,もくもく会オンリーでしたが,今回から,入門者トラックも併設し,fukuoka.exアドバイザーズ/キャストに質問できるようにアップグレードしました

私,山崎も参加します! この記事の延長線上のものを作ろうと思っています。

お申込みはコチラから
https://fukuokaex.connpass.com/event/100659/
image.png

4
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0