fugafuga.write

日々のログ



Hex に自作ライブラリを登録する

この前とても役に立つコマンド(個人差有)

github.com

を作った。

Hex に登録して escript.install すると作ったコマンドをすぐ共有できてよさそうなのでやる。

環境

Elixir 1.5.2

Hex にユーザー登録する

mixコマンド は elixir に同梱されている。

> mix hex.user register
By registering an account on Hex.pm you accept all our policies and terms of service found at https://hex.pm/policies

Username: tokoyax
Email: tokoyax.dev@gmail.com
Password:
Password (confirm):
Registering...
Generating API key...
Encrypting API key with user password...
You are required to confirm your email to access your account, a confirmation email has been sent to tokoyax.dev@gmail.com

API keyは~/.hex/hex.configに保存される。
メールが届くので confirm するとアカウントが作成される。

mix.exsの編集

ライブラリのページに記載されるメタデータを編集する

defmodule No.Mixfile do
  use Mix.Project

  # 追加
  @description"""
  This is `no` command that outputs `n` implemented in Elixir.
  """

  def project do
    [
      app: :no,
      version: "0.1.0",
      elixir: "~> 1.5",
      name: "No",
      description: @description, # <= 追加
      package: package(), # <= 追加
      escript: escript_config(),
      start_permanent: Mix.env == :prod,
      deps: deps()
    ]
  end

...

  # 追加
  def package do
    [
      maintainers: ["tokoyax"],
      licenses: ["MIT"],
      links: %{ "Github": "https://github.com/tokoyax/no" }
    ]
  end

Hex へ登録

Passphrase を聞かれるのでアカウント作成時のパスワードを入力する。

> mix hex.publish
Passphrase:
Publishing no 0.1.0
  Files:
    lib/no.ex
    mix.exs
    README.md
  App: no
  Name: no
  Description: This is `no` command that outputs `n` implemented in Elixir.
  Version: 0.1.0
  Build tools: mix
  Licenses: MIT
  Maintainers: tokoyax
  Links:
    Github: https://github.com/tokoyax/no
  Elixir: ~> 1.5
Before publishing, please read the Code of Conduct: https://hex.pm/policies/codeofconduct
Proceed? [Yn] Y
Building docs...
Compiling 1 file (.ex)
Generated no app
The "docs" task is unavailable. Please add {:ex_doc, ">= 0.0.0", only: :dev} to your dependencies in your mix.exs. If ex_doc was already added, make sure you run the task in the same environment it is configured to
** (Mix) The task "docs" could not be found. Did you mean "do"?

なんかエラーが。

{:ex_doc, ">= 0.0.0", only: :dev}が無いので追加しないといけないっぽい。

mix.exsを編集する

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      {:ex_doc, ">= 0.0.0", only: :dev}, # <= 追加
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"},
    ]
  end

もう一度実行

> mix hex.publish
...
Proceed? [Yn] Y
Building docs...
Unchecked dependencies for environment dev:
* ex_doc (Hex package)
  the dependency is not available, run "mix deps.get"
** (Mix) Can't continue due to errors on dependencies

またエラーが。

依存関係のパッケージが無いのでmix deps.getしないといけませんよーとのこと。 次のアクションを促してくれるのは親切でとてもよい。

> mix deps.get
Running dependency resolution...
Dependency resolution completed:
  earmark 1.2.3
  ex_doc 0.18.1
* Getting ex_doc (Hex package)
  Checking package (https://repo.hex.pm/tarballs/ex_doc-0.18.1.tar)
  Fetched package
* Getting earmark (Hex package)
  Checking package (https://repo.hex.pm/tarballs/earmark-1.2.3.tar)
  Fetched package

Ok, 再度実行

> mix hex.publish
Passphrase:
Publishing no 0.1.0
  Files:
    lib/no.ex
    mix.exs
    README.md
  App: no
  Name: no
  Description: This is `no` command that outputs `n` implemented in Elixir.
  Version: 0.1.0
  Build tools: mix
  Licenses: MIT
  Maintainers: tokoyax
  Links:
    Github: https://github.com/tokoyax/no
  Elixir: ~> 1.5
Before publishing, please read the Code of Conduct: https://hex.pm/policies/codeofconduct
Proceed? [Yn] Y
Building docs...
==> earmark
Compiling 3 files (.erl)
Compiling 24 files (.ex)
Generated earmark app
==> ex_doc
Compiling 15 files (.ex)
Generated ex_doc app
==> no
Compiling 1 file (.ex)
Generated no app
Docs successfully generated.
View them at "doc/index.html".
Publishing package...
[#########################] 100%
Package published to https://hex.pm/packages/no/0.1.0 (1b7e3d36abb1e88b60b9fd3872cc251dc32ef3aa19a13ead26bd040644af42d3)
Publishing docs...
[#########################] 100%
Docs published to https://hexdocs.pm/no/0.1.0[f:id:tokoyax:20171118170418j:plain]

OK

hex.pm にアクセスしてみる。

f:id:tokoyax:20171118170418j:plain

https://hex.pm/packages/no

SUCCESS 😇 😇 😇 😇 😇

escript.install してみる

escript.install – Mix v1.6.0-dev

If an argument is provided, it should be a local path or a URL to a prebuilt escript, a Git repository, a GitHub repository, or a Hex package.

とあるように、github など Hex 以外からも install できるらしい。便利。

> mix escript.install hex no
Running dependency resolution...
Dependency resolution completed:
  no 0.1.0
* Getting no (Hex package)
  Checking package (https://repo.hex.pm/tarballs/no-0.1.0.tar)
  Using locally cached package
Compiling 1 file (.ex)
Generated no app
Generated escript no with MIX_ENV=prod
Found existing entry: /Users/takuya/.mix/escripts/no
Are you sure you want to replace it with "no"? [Yn] Y
* creating /Users/takuya/.mix/escripts/no

warning: you must append "/Users/takuya/.mix/escripts" to your PATH if you want to invoke escripts by name

実行可能ファイルは、~/.mix/escripts に install される。 warning にもあるように PATH 通さないと使えないので気をつけてね、とのこと。

まとめ

  • elixir さえインストールされていれば結構お手軽にコマンド配布できたので最高という感想
  • ドキュメントの整備はまた気が向いたらやる

(参考)
* ElixirのライブラリをHexに公開する | Developers.IO

プログラミングElixir

プログラミングElixir

'no'コマンドについての本当にちょっとした話

この記事に触発されて、Elixir の練習として似たようなコマンドを作った。

Unixコマンド”yes”についてのちょっとした話 | コンピュータサイエンス | POSTD

この世の全てを否定するコマンドno

記事内ではyesコマンドが扱われていたがそのまま作ってもしょうもないので、noコマンドを作ることにした。 仕様はほぼyesと同じ。標準出力に永久にnを出力し続ける。

こんな感じで使えるようにする。

> no
n
n
n
n
n
n
n
...

または、

> no | sh work_a_lot.sh

annoying boss に

「安月給でもっと働け!!プロ意識をもて!!やりがいで駆動しろ!!」と言われましたか?

そういう時にこのコマンドが役に立つはずです。

※ 効果には個人差があります

さっそく作る

環境

> elixir -v
Erlang/OTP 20 [erts-9.1.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Elixir 1.5.2

プロジェクト作成

> mix new no
> cd no

mix.exs修正

Elixir で実行可能ファイルを作成するには、escriptを使えとのこと

Erlang -- escript

  • line:9 escript を使用するためにモジュールを指定
  • line:22-24 モジュール名などを返す関数を書くのが良さげ

mix.exs

ここで指定した module の No.main/1がエントリポイントになる

実装

普通にループするだけじゃあしょうもないので、プロセスをたくさん生成してそれぞれがnを出力し続けられるようなオプション-pを追加した。 あと、その並列実行の様を観測できるように-dでPIDを見られるようにもした。

OptionParser めっちゃ便利。

こうやったほうがCOOLだよ!などがあれば教えてもらえるととても嬉しいです。

no

ビルド

実装が済んだらビルド mix.exsがあるディレクトリで実行する

> mix escript.build

カレントディレクトリに実行可能ファイルが生成されるはず

実行

カレントディレクトリに

> ./no -p 100
n
n
n
n
n
...

とりあえず動いている

デバッグオプション有り

> ./no -p 100 -d
{"n from process no.47", #PID<0.122.0>}
{"n from process no.47", #PID<0.122.0>}
{"n from process no.47", #PID<0.122.0>}
{"n from process no.40", #PID<0.115.0>}
{"n from process no.47", #PID<0.122.0>}
...

やったぜ

速度的にどうなの

速度が気になったので計測してみた

> ./no | pv -r > /dev/null
[93.7KiB/s]

yesコマンドはというと、

> yes | pv -r > /dev/null
[31.6MiB/s]

noコマンド、桁違いに遅くて笑っちゃう!!!

まあまあ落ち着け、並行処理で逆転だぜ!

> ./no -p 100 | pv -r > /dev/null
[1.12KiB/s]

より遅くなるってどういうことなの...

まとめ

  • 言語の練習題材としてLinuxコマンドを再実装するのは良い
    • 機能のサイズ的に手頃なのが多い
  • |>で処理繋いでいくのは気持ち良い
  • なんで遅くなるのかわからん
    • 気が向いたら調べる
  • Hex への登録

気が向いたら続く。

github.com

(参考)

プログラミングElixir

プログラミングElixir

Vimが重いのでつらい

Ruby 書いてる時に Vim が too slow で つらい

  • スクロールが遅い
  • カーソル異動が遅い

syntax off にしてみる

軽くなる
が、syntax highlight なくなるのは論外

原因は syntax の解析か

fold method の設定を見直す

【Vim】Ruby書くときにVimが重くてつらいときは - Qiita

これはもともとやってた。

set lazyredraw を設定してみる

Vim slow with ruby syntax highlighting - Stack Overflow

ここにあるように、set lazyredrawset ttyfastすると多少キビキビ動くようになった。

set re=1 などを設定してみる

設定値を切り替えることによって、Vim 内部の正規表現エンジンを切り替えられるみたい。 デフォルトはre=0なのでre=1などに変更したが、体感できる変化はなかった。