ハーフマラソンに出場してきた

f:id:amagitakayosi:20170417173353p:plain

3月末、大阪で開催されたハーフマラソンに出場した。
ついでにスーパー銭湯でのんびりしたり、鶴橋で焼肉を食べたりした。

マラソン

淀川沿いを往復するやつ。

第7回 淀川国際ハーフマラソン|サンスポマラソン

去年なんとなくジョギングしてた時22キロくらい走ってたりしたので、まあ行けるでしょ、というノリでエントリーした。
しかし、マラソン大会の経験は当然無いし、子供の頃から体力ゼロで通してきたので、結構不安になって朝のジョギングの頻度を上げたりしていた。
目標は低く、「完走できればOK」とした。

天気予報によると当日は午後から雨だったので、前日にはスポーツショップや100均に買い出しに行った。
ウエストバッグは持っていたものの、重さや収納を考えて、こちらの商品を購入した。

FlipBelt(フリップベルト) スポーツウエストポーチ FBB ブラック M

FlipBelt(フリップベルト) スポーツウエストポーチ FBB ブラック M

当日午前中は良い感じに涼しい天気だった。
ファミリーコース?みたいなのもあり、家族連れがおおい。
主催の人が歌ってたり、NMB?かなんかの曲にあわせて準備体操が始まったり、平和な感じ。

これ司会してるのラジオDJかなんかかと思ったけど、どうやら有森裕子本人らしかった。異常にテンション高い。
有森さん、スタート地点でも「いってらっしゃーい頑張って〜!フォォォおお!!」みたいな感じで、やっぱアスリートってエネルギーすごいんだなって思った。

序盤は「エッこんなゆっくり走っててもみんなスイスイ追い抜けちゃうの?」って思うくらい楽々で、道路脇の芝生の部分を走ってたりしたんだけど、これが裏目に出たのか、半分すぎた辺りから追い抜かれることが多くなった。
追い抜かれると焦ってしまって余計しんどくなるので、後半は目をつぶって走ったりしてた。

給水所では、水のほかにも一口大にカットされたアンパンやクリームパンが配られていた。
意外と制限時間までは全然余裕だったので、ちょっと立ち止まって味わって食べた。

最後のほうは足が半分麻痺してたけど、どうにか完走出来てよかった。
順位を見ると半分より下なのでやっぱり悔しい気はする。

こちらは当日のようすです。
走りながら撮るのも楽しい。

スーパー銭湯

マラソンのあとは、会場から電車で30分ほどのスーパー銭湯へ向かった。
街なかにあり、程よい広さでいろんな種類のお湯に浸かれて便利。

www.nobuta123.co.jp

日曜の夕方だが、部活帰りの少年たちが非常に多かった。
高校生や大学生のバイトが大量に働いていたのもあり、自分が大人サイドの人間って感じがしてしまう。

銭湯なのに美容室やレストランが併設されていたり、建物内の施設では自販機含め全て独自システムで決済したりと、一つの国家のような様相を呈していた。

鶴橋で焼肉

たっぷり筋肉を痛めつけたという名目で焼肉へ。
以前から鶴橋に行きたかったんだよ

www.yakinikusora.jp

鶴橋は焼肉屋さんだらけだが、今回は一番有名っぽいとこにした。
ホルモン5種盛りがお得で旨い。

ごちそうさまでした。

Scala入門としてCLIツールを作り、Scala.js, React, ScalaCSSでサイトを作った

fand.github.io

今年2月からScalaのチームに異動し、Scala入門している。

2月中はゆっくりコップ本を読んでいたのだけど、やっぱり手を動かさないと自信が付かないので、何かツールを作る事にした。
ついでにGitHub PagesもScala.jsやScalaCSSで実装してみた。

つくったツール

github.com

!!! 実用性は度外視しています !!!

レポジトリをまるごとコピーしてくれるやつ。
ブランチを移動する度にコンパイルで時間かかるのを回避するため、ブランチ毎にコピーしたらいいのでは、という発想(上手く行ってるかはわからない……)。
手で cp -r するのが一番はやいし、ツールを作るにしても普段だったらJSで書くとこだけど、今回はせっかくなのでScalaCLIツールを作ってみた。

使い方

brewでインストール可能。

$ brew tap fand/clonepool
$ brew tap fand/clonepool

clonepool -h でかっこいいヘルプが出る。

f:id:amagitakayosi:20170407162300p:plain

仕組み

内部では motemen/ghqpeco/peco を利用している。
$ clonepool rails/rails my-branch と入力すると以下の処理が走る。

  • $ ghq get rails/rails により、 $(ghq root)/github.com/rails/rails にレポジトリがクローンされる
  • ~/.clonepool/github.com/rails/rails/my-branch にコピーを作成
  • my-branch ブランチにチェックアウト

引数なしで $ clonepool とすると ~/.clonepool 以下のディレクトリを一覧できる。
cd $(clonepool | peco) とすると絞り込みつつ移動できて便利。

f:id:amagitakayosi:20170407162312g:plain

実装について

ほとんど scala.sys.process.Process を利用してシェルコマンドを実行しているだけ。
Gitレポジトリの操作ということで、最初はJGitを利用していたんだけど、シェルコマンドを利用したほうが楽なことがわかったのでやめてしまった。

Processの実行は scala.util.control.Exception.allCatch でラップしている。
allCatch {} は、ブロックを評価した結果をSomeで返し、例外が出たらNoneを返してくれる。

seratch.hatenablog.jp

個人的には、CLIツールを実装するときは気軽に死にたい。
JSだと、大部分ををPromiseベースで実装して、一番外側で全部catchするというのをよくやっている。
今回は getOrThrow という関数を作って、気軽に死ねるようにした。

https://github.com/fand/clonepool/blob/master/src/main/scala/example/Util.scala#L9

CLIツールを作るためのライブラリは SCOPTCLIST などがあるが、あんまり好みじゃなかったので今回は利用していない。
かっこいいヘルプは ansi-interpolater を利用して実装した。

homebrewでインストールできるように

Scalaのライブラリは、maven centralに登録したり、オレオレmavenレポジトリを作って公開するらしいけど、CLIツールを配布できるか良くわからなかった。
conscript を使えば簡単に配布できるらしいけど、利用者もconscriptをインストールする必要があってなんか面倒。
sbtはhomebrewで配布されているので、今回はsbtを真似てみることにした。

今回つくったformulaはこんな感じ。

https://github.com/fand/homebrew-clonepool/blob/master/clonepool.rb

sbtのformulaと大体同じ。
jarファイルをlibexecに配置し、bin/clonepoolに java -jar clonepool.jar するシェルスクリプトを置いている。

jarファイルはsbt-assemblyというsbtプラグインを利用している。
$ sbt assembly を実行すると勝手にjarが出来て便利。

github.com

GitHub Pagesについて

http://fand.github.io/clonepool

今回の目的はScala入門、ということでGitHub PagesもScala.js + ScalaCSS + Reactで構成した。
Octocatをクリック(またはタップ)すると回転します。

f:id:amagitakayosi:20170407162432g:plain

Scala.js

www.scala-js.org

AltJSの一種。Scalaで書かれたコードをJSに変換する。
一昔前に「機能もヤバいしファイルサイズもデカ過ぎてヤバい」って話題になってたけど、今では大分マシになってる。
今回のコードはgzip圧縮済みで122 KBだ。

sbt fastOptJS または sbt fullOptJSコンパイルする。
~fastOptJS とするとファイル変更をwatchしてくれる。
fullOptJS を実行すると70秒かかる……。

この前Webpack用のローダーが公開されたりしてたけど、今回はsbtで開発した。

https://github.com/mrdziuban/scalajs-loader

Scala.js自体の内容に関しては特に言うことなくて、ふつうにScalaって感じ。
ただ、あるクラスの子オブジェクト一覧を取得したくて scala.reflect.runtime を使おうとしたけど、なんか上手くいかなかったな、そういえば。

scalajs-react

Scalaは現代的な言語なのでReactも書けます

github.com

Scala.jsからReactを利用するためのライブラリ。 JSXの代わりに、 <.div() とか ^.src := "hoge" みたいな感じでDOMを記述する。

import japgolly.scalajs.react.vdom.html_<^._

<.ol(
  ^.id     := "my-list",
  ^.lang   := "en",
  ^.margin := 8.px,
  <.li("Item 1"),
  <.li("Item 2"))

(ドキュメントより抜粋)

記法自体は慣れたらそんなに難しくない。
しかし、コンポーネント自体とは別にBackendというクラスを書く必要があったり、独自の概念がたくさんあって大変。
何より実装がほとんど読めないのがしんどい……。

ScalaCSS

CSSScalaで書ける時代……!

github.com

scalajs-reactと同じ作者が開発している。
Super type-safe CSS とのこと。???????
例えば、widthなどのピクセルを指定する場所に無効な文字列を書くと、型が合わないといって怒ってくれる。

ScalaCSSはStandalone APIとInline APIの2種類のAPIを持つ。
単なるAltCSSとして使う時は Standalone APIを、CSS in JSを行なうときはInline APIを利用する。
今回は、コンポーネント毎のスタイルはInline APIで生成し、ページ全体で共通のスタイルはStandalone APIを利用して記述した。

この辺はtakezoeさんの記事で解説されてる。

takezoe.hatenablog.com

CSS in JSライブラリとしては、生成されるクラス名が .MyComponent--button のように予想しやすいクラス名になってしまうのが難点。 (多くのCSS in JSライブラリでは、クラス名をランダムな文字列にすることで、意図しないクラス名の衝突を回避している)

他にも、コンパイル時間が長かったり、対応していないCSSプロパティが多いので、得られる恩恵も割に合わない気がする……。 が、これも慣れてしまえば、書くの自体はそんなに難しくない。

最終的なコンポーネントの定義は以下のようになった。

package io.github.fand.clonepool.docs.components
import japgolly.scalajs.react._, vdom.html_<^._
import scalacss.Defaults._
import scalacss.ScalaCssReact._

object Link {
  val component = ScalaComponent.builder[Tuple2[String, String]]("Link")
    .render_P(t =>
      <.a(
        LinkStyle.link,
        ^.href := t._2,
        t._1
      )
    )
    .build
}

object LinkStyle extends StyleSheet.Inline {
  import dsl._
  val link = style(
    color(c"#EFF"),
    pointerEvents := "auto"
  )
}

その他

Sketchでロゴをつくったり、 http://realfavicongenerator.net/favicon生成したりした

今回学んだこと

  • Scala
    • allCatchで雑にエラーを扱う方法
    • Scala.js
    • Scala.js + React
    • ScalaCSS
  • homebrewのformulaを書く方法

今度はGolang + GopherJS入門しようかな〜〜