Kotlin の coroutines + Android で簡単なカウントダウンタイマー

環境

Kotlin の coroutines 環境セットアップ

ググっても、Kotlinのバージョンによって差がありそうだったので素直に公式を見る。

github.com

私の手元では、↓2つのファイルに手を加えればOK

build.gradle (Module)

dependencied {
    ...
    def kotlin_coroutines_version='0.16'
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
    ...
}

gradle.properties

kotlin.coroutines=enable

coroutine を使う

非同期処理自体はこんな感じ。 launch は kotlinx.coroutines.experimental.launch UI は kotlinx.coroutines.experimental.android.UI delay は kotlinx.coroutines.experimental.delay kotlinで全て完結する。

launch(UI) {
   while(isActive) {
        delay(1000)
        time--
    }
}

launch の戻り値は kotlinx.coroutines.experimental.Job で、 start()stop() といったいかにもなメソッドを持ってる。 なので、それをプロパティにもたせて、

class Timer(time: Int) {
    private var countDownJob: Job? = null

    fun countDownStart() {
        if (countDownJob != null) { return }
        countDownJob = launch(UI) {
            while(isActive) {
                delay(1000)
                time--
            }
        }
        countDownJob?.start()
    }

    fun countDownStop() {
        countDownJob?.cancel()
        countDownJob = null
    }
}

といった感じにすれば、カウントダウンタイマーの処理部分ができあがる。 *1

*1:毎回 launch してるのが無駄な気がする。

firedropを使ってみた

firedrop.ai

ずっと前に Subscribe してて忘れてたんだけど、beta版のお誘いメールが来て思い出したのでやってみた。
タイトルとリンクしか無いけど、作ってみたのが↓。

https://yasuhiroki.firedrop.me/

「AIがデザインしてくれる貴方のWebサイトを作るサービス」という触れ込みなんだけど、
今のところは、チャット形式で進むチュートリアルで簡単にWebサイトを公開できるサービスな感じ。

チャットっぽい画面に幾つかの選択肢が用意されていて、
たとえば Change Layout とか Publish Site といったボタンがあるのでクリックしてWebサイト作りを進める。
LayoutとかColorは勝手にいい感じにしてくれる…らしいんだけど、レパートリーが少ない気がする。

Beta版なので機能が少ないだけかな。
私自身、デザインはからっきしなので、機械にお願いできるならお願いしたい。期待してる。

Elixir Conf 2017 に行ってきた

www.elixirconf.jp

行ってきた。Elixir歴2週間(といってもハンズオンでちょっと触った程度)でも十分楽しめた。

経緯

Elixirはずっと気になってたので、イベントが告知された段階ですぐに申し込んだ。
全く触ってなくてもとりあえず行ってみようと思っていたが、Elixir Confの申込後にハンズオンの募集が始まったので、

  1. Elixir Conf 申し込み
  2. ハンズオン申し込み
  3. ハンズオンに行く
  4. Elixir Conf に行く

というスタックのようなスケジュールだった。
当初は、全く経験なしでも行こう、と思っていたが、実際のところ、ハンズオンで説明を受けながら触った経験があって良かった。
それが無かったら、今ほど Conf を楽しめてなかったかもしれない。

感想

始めはElixir作者 José さんのKeynote
ゆっくりで、簡単な英語を使ってくれていて分かりやすかった。
今後の予定として型について言及があり、質問もTwitterも盛り上がってた。

午前中は基礎的な話。
Rubyが好きだけど業務ではJavaScriptなエンジニアなので、関数型プルぐラミング・並列プログラミングのどちらも馴染みがなかったが、 どちらもきちんと説明してくれていたので有難かった。
「Elixir Way」を分かってないと、逐次的な実装になりがちで、それって並列で処理されないからせっかくElixirで書いてるのにもったいない、らしい。頭で分かっても実際に実装できるかは…慣れだなぁ….。

午後からはガチ話が増えてきて、分かるようで分からない話がちらほら。OTPはまだ全く分かってない。
Elixir/Erlangの特性が活きる、小さな処理を大量にさばくために活用している話がほとんど。
もう少し触ってからスライドを見直すのが良さそうだけど、そもそも今の私には紹介されたような事例と出会う場面がなさそう。

LTはやっぱり楽しい。こういうイベントにLTは欲しい。
特別枠はすごく熱い話だった。

最後に時雨堂のVさんのKeynoteで締めくくり。
フリートークに近い話の進め方だったけど、Erlangをがっちり使い続けた方の話なので、これが面白くないわけがない。楽しすぎる。

全体を通して刺激ある一日だった。
無線環境も安心のCONBUさんで快適だった。
電源がなかったことだけが悩みだった・・・。

Elixir初心者向けハンズオンに行ってきた

beam-lang.connpass.com

Elixir楽しい。

きっかけ

1年くらい前に Rebuild.fm や 勉強会などで Elixir の名前を知って興味を持っていたが、 同じくらいの頃に業務で TypeScript を触り始めたので、同時 2つの言語を勉強する力が無く、ずっと放置していた。 最近になって、ようやく時間に余裕ができたぞ、と思ったタイミングでこのイベントを知り、すぐに申し込んだ。

流れ

会場はレバレジーズ。 会場の案内や挨拶の後、 @ohrdevさんによるElixirの概要説明を受け、いざハンズオン。

やったこと

github.com

↑を進めてElixir でチャットアプリを作った。 Pub/Subも WebSocket も初めてだったけどすんなり動いた。

Twitter/Gitter/口頭で質問できるので、進捗ダメです、なことにはならない、と思う。

一通り終わったら人によってやることは様々で、私は Elixir School を読み進めてた。 パターンマッチ面白い。この辺もっと深掘りしたい。

メモ

以下、メモ書き

  • Elixirはコンパイル言語(知らなかった!)
  • %{a: 1, b: 2} == %{:a => 1, :b => 2} != %{"a" => 1, "b" => 2 }
    • 特に Json の手癖で %{"a": 1} とか書くと、それは %{"a" => 1} とは別物になる
    • Atom(Rubyで言うSymbol) かどうかが鍵
      • 何となく分かるけど 腑に落ちてない。触り慣れれば分かってきそう。
  • OTP
    • Open Telecom Platform
    • 並列プログラミング用のフレームワーク・開発環境・ライブラリ集
    • 汎用的な処理のパターン(ビヘイビア)を提供
    • 全く分かってないので調べる
  • mix
    • mixコマンドで Elixir のプロジェクトを作成・管理する
      • こういうツールが標準で入ってると便利…

おまけ

ファイルの空行を削除するElixirのワンライナー書いた

FLOCSSなディレクトリ・ファイルを作成するシェル

無理やりワンライナーっぽくしてみた。

echo foundation/{_base,_reset} \
  layout/{_footer,_header,_main,_sidebar} \
  object/component/{_button,_dialog,_grid,_media} \
  object/project/{_articles,_comments,_gallery,_profile} \
  object/utility/{_align,_clearfix,_margin,_position,_size,_text} \
  | \
  xargs -n1 -I% bash -c \
  'mkdir -p $(dirname scss/%); [ ! -f scss/%.scss ] && { : > scss/%.scss; echo "@import \"%\";" >> scss/app.scss; }'

もうちょっと綺麗にできるといいなぁ。

yarnpkgは~/.yarnrcを見ている

なので、シェルをカスタムするためのオレオレ設定を ~/.xxxrc に書いてるとあかんよ、という話。

yarnpkg.com

yarnを使おうとしてインストールしたけど動かなかった。

$ yarn init
yarn init v0.15.1
error SyntaxError: Unknown token 1:0
    at Parser.unexpected (/usr/local/Cellar/yarn/0.15.1/libexec/lib/node_modules/yarn/lib-legacy/lockfile/parse.js:218:11)
    at Parser.parse (/usr/local/Cellar/yarn/0.15.1/libexec/lib/node_modules/yarn/lib-legacy/lockfile/parse.js:323:14)
    at exports.default (/usr/local/Cellar/yarn/0.15.1/libexec/lib/node_modules/yarn/lib-legacy/lockfile/parse.js:13:17)
    at /usr/local/Cellar/yarn/0.15.1/libexec/lib/node_modules/yarn/lib-legacy/registries/yarn-registry.js:105:62
    at next (native)
    at step (/usr/local/Cellar/yarn/0.15.1/libexec/lib/node_modules/yarn/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
    at /usr/local/Cellar/yarn/0.15.1/libexec/lib/node_modules/yarn/node_modules/babel-runtime/helpers/asyncToGenerator.js:28:20
    at run (/usr/local/Cellar/yarn/0.15.1/libexec/lib/node_modules/yarn/node_modules/core-js/library/modules/es6.promise.js:87:22)
    at /usr/local/Cellar/yarn/0.15.1/libexec/lib/node_modules/yarn/node_modules/core-js/library/modules/es6.promise.js:100:28
    at flush (/usr/local/Cellar/yarn/0.15.1/libexec/lib/node_modules/yarn/node_modules/core-js/library/modules/_microtask.js:18:9)

lockfile がどうのと言っているが、 yarn.lock ファイルは作ってない。 GitHubのIssueを漁ったところ

Getting SyntaxError when running basic command · Issue #613 · yarnpkg/yarn · GitHub

~/.yarnrc が原因だと判明。

私は、色々なツール・コマンド用のオレオレ設定を ~/.xxxrc に書いて source で読み込むようにしていた。 その癖で ~/.yarnrc を作って、 export PATH=~/.yarn/bin:$PATH などと設定していたのだけど、それが悪かった。

現在のyarnは、yarn自身の設定を ~/.yarnrc から読み込む。

https://github.com/yarnpkg/yarn/blob/b0611a6ee5220b0b1e955b271b6140640158f96c/src/registries/yarn-registry.js#L50

設定ファイルの管理場所考え直そう..

jqでURLエンコーディング

$ echo "a+b=b&c=hoge&d=hfua piyo" | jq -R '[split("&")[] | ([split("=")[] | @uri] | join("="))] | join("&")'
"a%2Bb=b&c=hoge&d=hfua%20piyo"

jq には @uri で URLエンコーディングする機能がある。 & で split して、= でさらに split して、片っ端から @url して、 = と & で join し直す、という仕組み。

もうちょっとシンプルに出来そう。