12/5
Elixir を使って製品を作ってゐると、release して此れ程の時が経ち此れ程の人が利用してゐるのに樣々のものが足りない。此の世では、必要なものは作る事に成ってゐるさうだ。なので一つづつ作ってきた。
みなさんも一つづつ作ってゆきませう。世界。
- holiday_jp
- inner_cotton
- Mnemonics
- PQueue2
- stream_gzip
- stream_hash
- witha
holiday_jp
Japanese holiday.
Ruby にはholiday_jpと云ふ便利な gem が在る。日本の休日を database にしたものだ。
休日と云ふのは規則的な樣だが、法律で決まるものであり、法律の改正によって變はるものだ。年に 20 日弱しか無い休日は數十年前から先迄樂に羅列できる。複雜な規則を法律の改正日で条件分岐しながら書き起こすより、羅列して引いてくるはうがずっと樂で bug を出しにくい。千年後はどうなるかわからないが当分は充分である。
此の Elixir のholiday_jpは、Ruby の holiday_jp と同じ data を使ってゐる。函數は三つ用意してある。between/2
とholiday?/1
とon/1
だ。
iex> HolidayJp.between ~D[2016-03-01], ~D[2016-03-31] [ %HolidayJp.Holiday{date: ~D[2016-03-20], week: "日", week_en: "Sunday", name: "春分の日", name_en: "Vernal Equinox Day"}, %HolidayJp.Holiday{date: ~D[2016-03-21], week: "月", week_en: "Monday", name: "振替休日", name_en: "Holiday in lieu"}, ] iex> HolidayJp.holiday? ~D[2017-01-02] true iex> HolidayJp.holiday? ~D[2016-01-02] false iex> HolidayJp.on ~D[2017-02-11] [%HolidayJp.Holiday{date: ~D[2017-02-11], week: "土", week_en: "Saturday", name: "建国記念の日", name_en: "National Foundation Day"}]
inner_cotton
Collection of recommended Elixir check utilities.
幾つか application や library を作ってゐると幾度も同じ library を入れる事に成る。静的 check tool でいつも使ふものを集めた。私の作ったものには全て此のinner_cottonを入れてある。意味は「中綿」、Lint(糸屑)を集めたもの。
現状では以下のものが入る。
- Credo : Lint, coding style enhancer.
- Dialyxir : Type checker using Dialyzer. Erlang 附屬の型檢査 tool を實行する。
- InchEx : Document (ExDoc) improver.
HEAD では更に次のものが入る。
- stream_data : Property base testing like QuickCheck. 多數の random data を使って性質 test を書ける。性質が常に成り立つか檢査するかのやうな事に使ふ。
- EyeDrops : Guardの樣に、file の變更を監視して command を實行する。
mix cotton.init
で各 tool 用の設定 file を置き、mix cotton.lint
で Credo と Dialyzer と Inch が走り、mix test
でいつも通り test が走り、mix cotton.watch
で file の變更に合はせて lint と test が走る(HEAD では)。今はExCoverallsを入れやうとしてゐる。
Mnemonics
Read only data store for Elixir: fast, concurrently, for large data & hot reloadable.
Mnesia に匹敵しさうな名前を考へたらMnemonicsに成った。皮肉は效いてゐないが……。
數十 MB 位いの readonly data を on memory に置いて讀み出す爲のものだ。Ruby のActiveHashが Elixir にも欲しくて作った。Read only な ETS table を管理する library として在る。同じ table 名の data を複數 version 管理できる。realtime に data を差し替へる爲だ。
version と data の cache 機能を附け終へた所だ。Mnemonicsを使った code が testable にならないのが一番の課題で、次は其れに取り組まうとしてゐる。ExMachinaの擴張を書く事に成ると思ふ。
PQueue2
Priority queue that wraps pqueue2.
優先度附き queue。
優先度附き queue すら無かったのか何故作ったと思ふかもしれぬ。私もさう思った。然して調べてみると「優先度附き queue」と名乗る Elixir の library は幾つも在った。私は全て調べた。結果、優先度附き queue として動作する實裝は無かった。同じ優先度からは random に出てくるものも在ったし(此れはPSQで、但し map としても機能する好いものだ)、一番 unique な實裝は LIFO として動いた、即ち優先度附き「stack」であった。辛うじて動いた一つはとっくに開發が放棄されてゐた。
Elixir ではなく Erlang にはちゃんとした實裝が在った。pqueueだ。此れを Elixir から便利に呼び、Enumerable と Collectable を實裝したものがPQueue2である。今作ってゐる application の背骨に使ってゐる。
stream_gzip
Gzip or gunzip a stream.
Elixir の Stream は遲くて嫌はれてゐるかもしれないが、pararell に處理する程ではない場面で少ない memory で大きな data を手軽に扱へる好いものだ。stream_gzipは data 全体を memory に載せずに gzip / gunzip できる Stream だ。
"x.js" |> File.stream! |> StreamGzip.gzip |> Stream.into(File.stream! "x.js.gz") |> Stream.run
で gzip でき、
"x.js.gz" |> File.stream! |> StreamGzip.gunzip |> Stream.into(File.stream! "x.js") |> Stream.run
で gunzip できる。Web application で data を生成しつつ gzip で streaming
stream_hash
Stream into md4, md5, ripemd160, sha, sha224, sha256, sha384, sha512 hash.
上記stream_gzipを test する爲に作ったが、どこかで使へる事も在るだらう。
witha
With aspect: Monad chain, like Haskell's do
or Clojure's cats.core/alet
.
{:ok, value} | {:error, reason}
を返す函數を連鎖したくて作った。Elixir 標準の with 式で似た事はできるが、より各構造に特化した連鎖を書ける。
witha Witha.Error, [x1 <- {:ok, 1}, x2 <- {:ok, x1 + 1}], do: x1 + x2 # {:ok, 3}
nil | value
も連鎖できる。
witha Witha.Nilable, [x1 <- nil, x2 <- x1 + 1], do: x1 + x2 # nil
AST level (macro)で new (return) & flat_map (bind)する作りに成ってゐる。此れ丈だと with 式の亜種なので、もっと高度な抽象化を取り込みたい。
tokyo.ex #8
ヾ(〃l _ l)ノ゙