北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

トレイト境界の F: FnMut(u8) -> bool という記法について

rust で where の中でトレイト境界を書ける。そして、クロージャはトレイトで実現されている。ってことなんだけど、クロージャを表す型変数のトレイト境界の書き方はなんとも気持ちが悪い。

struct Cacher<T>
    where T: Fn(u32) -> u32
{
    calculation: T,
    value: Option<u32>,
}

Closures: Anonymous Functions that Can Capture Their Environment - The Rust Programming Language

トレイト境界と言えば T: Display + Clone とか、ジェネリックであれば <> を使って T: AsRef<str> みたいな記法になるはずだが、 () とか -> とはなんなのか。

答えから言うと、これは Fn ファミリー独自の記法のようだ。文法的にはこうなっている。 ->() を使う規則は TypePathFn命名されている。

TypePathFn :
( TypePathFnInputs? ) (-> Type)?

TypePathFnInputs :
Type (, Type)* ,?

Paths - The Rust Reference

これは Foo<(...), Output=B> の糖衣だとする文章も残っている。

rust-rfcs/0587-fn-return-should-be-an-associated-type.md at master · nox/rust-rfcs · GitHub

ここまで来ると、ああ、やっぱりクロージャはトレイトなんだなという思いになってくるが、現行ではこの規則で脱糖してもコンパイルすることはできず、 TypePathFn の記法を使わねばならない。

error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change. Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead (see issue #29625)
   --> src/main.rs:175:10
    |
175 | where F: FnMut<(u8,), Output=bool>
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^

VSCodeからWSL上のRLSを使うメモ (2)

ある朝突然、 cargo testVSCode Insiders から呼べなくなった。これを踏んでた。どうやら昨日の夕方に 1.36.0-insider がアップデートされて壊れたようだ(アップデートされた記憶はあまりない)。

github.com

以下に従って5月のビルド 1.35.0-insider に戻したら問題なく動いた。 Insider らしくてとてもよい(よくない)。

Access older Insider builds · Issue #46089 · microsoft/vscode · GitHub

VSCodeからWSL上のRLSを使うメモ

悲しいことにうまく動せていない。時間が解決してくれる気はする。

その1. Remote WSL環境

開発者版 VSCode insiders が必要。 VSCode とは別のアプリとしてインストールできるので気にせず入れて良い。Remote WSL 拡張を入れればそれで終わり。

その2 で使う useWSL は使わない。ほぼうまく動くが、なぜか rustfmt による整形が動かない上に、 Output View へログを一行も吐いてくれない*1ので調査もできなくて困る。

その2. RLS拡張のuseWSLを使う

RLS拡張 が想定しているのはおそらくこちらの使い方。

しかし、まず rustup の PATH が通らない。 issue 上がってそう だけど放置されてる感。拡張の設定で rustup の PATH を WSL 内の full path にすればこの問題は対処できる。

次に嫌なのが、 WSL 内の windowsファイルシステムのマウントが /mnt/固定であること/etc/wsl.confroot 設定を書いていると動かせない。

root を変えるのが面倒でここで諦めてしまったが、使っている人がいる機能であるはずなので多分動かせば動くのであろう root を変えたら動いた。あと、当たり前ではあるがこちらだと、 windowsファイルシステムにプロジェクトを置かなければならないという制約がある。

*1:その2でもきちんと動くようになったあとはログが出なくなったので、エラーが起きないとログは吐かないという話のような気もする

dockerで古いバージョンのperlを使う

Docker Hub に perlのイメージ が上がっていて便利なのだけど、残念ながら 5.24 までしかない。検索してみたけど他に良さげなイメージもなかった。

仕方がないので 自分でビルド をして上げておいた(自分で使う用)。幸い、以下のリポジトリにいい感じの Dockerfile が落ちてるので、これを落としてきて自前でビルドするだけで済んだ。

github.com

追記

5.14 と 5.16 はビルドできなかった。

LTSのubuntuを16.04から18.04へアップグレードした

以下に書いてあるとおり。

wiki.ubuntu.com

基本的に sudo do-release-upgrade を叩いただけ。sshd の config を置き換えていいかみたいなことを聞かれたので、触った覚えがないので不安を覚えつつ置き換えた。後は、質問に答えながら延べで数時間放置していたら終わっていた。

たしかに新しくはなったが、何が変わったかわからないレベル。 emacs がなぜか無くなっていたようなので、

$ sudo apt install emacs25-nox

した。今のとこそのくらい。

minillaは便利

songmu さんの WEB+DB の記事を読むのが良い。

gihyo.jp

リリーステストで、

Hoge.pm requires 5.010 due to explicit requirement 

で死んだときは Perl version 指定が正しいか確認する。 // とか使ってると 5.8 系はサポートできないというか、流石に 5.8 系は平成半ばにしてすでに終わっているのではないか。

xt/minilla/spelling.t ......... skipped: no ~/.spellunker.en   

が出てたときは touch ~/.spellunker.en するとPODのスペルチェックもやってもらえる。

CircleCIのsave_caheするPATHとdocker imageの相違

.circleci/config.yml に以下のように書いておいたら、ある時からキャッシュが効かなくなってハマった。

version: 2
jobs:
  build:
    docker:
      - image: perl:5.28
    steps:
      - checkout
      - restore_cache:
          key: cacheminil-v1
      - run:
          name: Install Minilla
          command: |
            cpanm Minilla
      - save_cache:
          key: cacheminil-v1
          paths:
            - "/usr/local/bin"
            - "/usr/local/lib/perl5/site_perl/5.28.0"
..以下略..

正しくは以下。いつまでも 5.28.0 のままではないのだ。

          paths:
            - "/usr/local/bin"
            - "/usr/local/lib/perl5/site_perl"

本当は - image: perl:5.28.0 を指定したいところだが、残念ながら https://hub.docker.com/_/perl を見てもない。