ux00ff

ビールとプログラミングと

jqのtodateでタイムスタンプ値を読みやすく

できるんじゃないか!

背景: jq コマンドで todate が使えるのをさっき知って。たぶん、何度目かに知って、感動しています。いいんだ、嬉しいことは何度あったっていいんだ。

つまりCloudWatch Logsのエポックタイム形式の表記を「2017-05-07T07:20:58Z」のような人間に優しい感じに拾えるということであって、これはとてもありがたい。filter-log-events がたいへん便利なんだけど時刻がエポックミリ秒なのがどうにも辛かったので。なお jq は 1.5 を使っています。

で、これができると、以下のようにCloudWatchのログが探せて結果がとても読みやすいわけです。

aws --profile=production logs filter-log-events \
    --log-group-name "/aws/lambda/my-awesome-log-group!" \
    --max-item 10 \
    --start-time `date -v-5M +"%s"` \
    --query "events" \
    --filter-pattern='REPORT' \
    --query "events[].{timestamp:timestamp,message:message}" | \
    jq '.[] | {: .timestamp | tonumber | (. / 1000) | todate , message: .message}'

しかし “–query” 内の関数に todate 追加されないものかなー、と思って見てみる。aws-cliのrequirements.txtでは boto/jmespath.git が参照されてます。実際に環境に利用されているのは jmespath-0.9.1のようですね(最新は0.9.2)。そしてpython版実装に対して todate 関数は実装されていません。残念。夢潰える。

さらっと見て jmespath の関数の実装は難しくないので送り付けちゃうのもいいのかもしれません。例えばエポックミリ秒を date に変換する millixec_to_date をこんな風に作ることで動くには動く。

    @signature({'types': ['number']})
    def _func_millisec_to_date(self, arg):
        from datetime import datetime
        return datetime.fromtimestamp(arg/1000)

じゃあどこに突っ込むかといえば、jmespath/functions.pyなわけなんですが、算術演算子がサポートされていない中で、エポック秒とエポックミリ秒を用意するのはスマートではないしなぁ。

Hello PlayFramework2

ちょっと仕事でWeb API周りを用意する必要がありまして。流れでScalaだろうなぁという話もあって、PlayFrameworkをチラ見していました。ん、Play2 Framework? PlayFramework2? どっちだろう。まあよい。

JSONを返すエンドポイントを作成するロールプレイ

プロジェクトを作成する

$ sbt new playframework/play-scala-seed.g8

ここでは play-api としました。

プレーンテキストなエンドポイントを作る

まずはエンドポイントに対応するコントローラとメソッドを作成します。ドキュメントによると、「Controllers are action generators」だそうです。かっこいいですね。もともと雛形として HomeControllerとか作られていますが、適当に新しいファイルを作っても作らなくてもいいです。controllersの下に作りましょう。

以下のような簡単な新しいコントローラを作成しました。アクセスすると hello world と挨拶してくれるイメージです。

package controllers

import javax.inject._
import play.api._
import play.api.mvc._

@Singleton
class GoodController @Inject() extends Controller{
  def hello = Action { implicit  request =>
    Ok("hello world")
  }
}
続きを読む

Scala x Matsuri

2月25日、2月26日にお台場で開かれたScalaMatsuri2017に参加してきました。初参加です。

とはいえスポンサーブース側でブースに張り付いていたので講演は聞けず、惜しいことをしました。後から資料を見て楽しむことにします。

ユーザー母数としてはけっして規模が大きいわけではないScalaという単一言語のイベントでありながら、運営母体がすごくしっかりしていて参加者も愛に溢れており、心から楽しむことができました。コミュニティの関心のノリがいろいろわかって、濃い人とお話もできて、実に濃密な二日間でした。スタッフの練度も高く、不愉快に感じたことは全くなかったと言っていいくらいです。それにしても同時通訳すごかったなぁ。

f:id:ux00ff:20170310115457j:plain

写真は公式Twitterのエントリからパクってるわけですが、ブースはこんな感じで出していました。今回スポンサーブースで建てた MacBook Proのプレゼント企画、課題として設定したクロスワードはおおむね好評だったけど、日本語読めない勢がちょっと残念そうだったので、次回は日本語に依存しないコンテンツ作らないとなと痛感しました。こんなに国際色豊かだとは思っていなかった。

これまではあまり技術系のコミュニティイベントに参加することはなかったのだけど、けっこう熱気に当てられました。いいもんですね。こういうの。有名人に全く知らずに話を振って苦笑されるシーンもたまに。講演者の @niw さんに「今日は何を目当てに来られたんですか」と聞いてしまったり、・・・いや、最大の失敗はきの子さんに「本名ですか」と聞いてしまったことです。思い出すと悶えるしかない。あるある。

Right value is right

Either型で成功と失敗を表すとき、どうして慣習的にLeftがエラー情報、Rightが正常系なんだろうと不思議だったんですが、Right(右)とRight(正常な)がかかってるっていうことを知って地味に感動しました。ダジャレか。

個人的には最初、先に(左側)正常値を書くのが自然かなと思っていたんですが、コードで戻り値をチェックする際 Right で正常というのは言われてみたら納得感あります。

scala> def div(c:Int ,d:Int) :Either[Exception, Int] = {
     |   d match {
     |     case 0 => Left(new Exception("d is 0"))
     |     case _ => Right(c/d)
     |   }
     | }

scala> div(5, 2)
res34: Either[Exception,Int] = Right(2)

scala> div(10, 0)
res36: Either[Exception,Int] = Left(java.lang.Exception: d is 0)

トレイトと自分型を利用してPAppletを分割する

引き続きProcessingです。自分型を設定したトレイトを利用すると、トレイトを実装する側のクラスを縛ることができます。Scalaスケーラブルプログラミングに「大きなクラスをトレイトを利用して分割するときにめっちゃ便利だよ」と書いていたが確かに便利ですね。

rubyの「おっと Enumerable をミックスインしたんだけど each メソッドがないよ?」みたいなことを、こちらはコンパイラが弾いてくれるのだな的理解で先へ進みます。

以下のようなデバッグ情報を表示するトレイトを作ったとして、

trait DebugView {
  self: PApplet =>

  def showDebugView(): Unit = {
    fill(255)
    textSize(13)
    textAlign(LEFT, TOP)
    text(s"(x, y) : ($mouseX, $mouseY)", 0, 0)
    text(s"${millis} ms", 0, 15)
    text(s"${frameRate} fps", 0, 30)
    text(s"${frameCount} frame count", 0, 45)
    text(s"mouse => ($mouseButton) key => ($keyCode)", 0, 60)
  }
}

利用側はこんな感じにします。

class Applet extends PApplet with DebugView {
  override def settings(): Unit = size(320, 240, JAVA2D)

  override def draw(): Unit ={
    background(0, 0, 100)
    showDebugView()
  }
}

f:id:ux00ff:20170221235542p:plain

トレイト側で self: PApplet => しているため、この DebugViewPApplet かまたはそのサブ型からしか利用できず、その制約の中で showDebugView のメソッド内では PApplet のメソッドを呼び出すことができます。

ProcessingをScalaで書く用のgiter8テンプレート

学習も兼ねて Processing 用のプロジェクトテンプレートを作って見ました。「scala-processing g8」 で検索しても最近のものが出てこなかったのでこれはきっと需要があるのだろうと信じて(苦しい)

コードはこちらに置きました。

sbt がインストールされている状態で、以下コマンドで Processing プロジェクトを作成することができます。なお sbt は公式通り brew でインストールしました

$ sbt new ma2saka/scala-processing.g8
続きを読む

読書の春

Scalaスケーラブルプログラミング第3版、なんだかんだで読み終わるまでに四日くらいかかった。良い本でした。 やっぱり紙の方が読みやすい・・・んだけど、お風呂で読んでいたのでちょいちょいふやけていたりします。

普通にJavaからの置き換えで学習してるだけだとたどり着かないあたり、for式の書き換えの理屈や implicit の使われ方、抽象メンバとトレイトの組み合わせ(withの前に初期化ブロック置く設計とか…)、それにLISTの実装解説はテンション上がった。少しだけ言語設計者やコンパイラの気持ちになれる気がします。ただあくまでも標準のコンパイラと実行系、そしてなにより言語の本であって、周辺のエコシステム周りについての情報は全くない。こちらは別にやっていかないとだ。どっから手をつけたものかしら。