Blogaomu

WEBアプリケーション開発とその周辺のメモをゆるふわに書いていきます。

kanazawa.rb meetup #55 に参加しました #kzrb

3月ももくもく会でした。ITビジネスプラザ武蔵サロンスペースというオシャレスペースでの初めての開催となりました。

kzrb.doorkeeper.jp

小学校にあった机や椅子を再利用しているらしいです。

図工室的な #kzrb

プログラミングElixir

前回に引き続き『プログラミングElixir』を読み進めました。6章「モジュールと名前付き関数」から7章「リストと再帰」の途中まで。関数型プログラミングの基礎的なところを押えた章になっていて、mapやreduceを実装してみたり少し複雑な処理を行う関数を実装する練習問題に取り組んだりしました。Scala関数型プログラミング慣れてきたかなーと思っていたんですが、問題をうまく再帰にすることができないなど手間取ってしまい練習問題を解くのに時間がかかってしまいました。

プログラミングElixir

プログラミングElixir

懇親会

加能商店は4時からオープンしていて立地的にも良いですね。懇親会では、採用時に何を聞くか聞かれるか→海外ではcourseraやudemyのカリキュラム修了済みっていうのを条件にしている会社も増えてきているらしい、部屋は目的別に分かれていた方が良い、家の基礎工事やってるときはちゃんと見に行った方が良い、などなど話してました。

鴨〜

明太子 on ポテサラ

でかい( ‘ω’)

次回

ペアプログラミングする回なんで楽しみ。4月だしRubyやっていくぞ!という方もぜひお待ちしております。 http://kzrb.org/meetup/56/

あと、Kanazawa IoTというコミュニティも爆誕していました。 kziot.connpass.com

kanazawa.rb meetup #54 に参加しました #kzrb

kanazawa.rb #54 に行ってきました。今回はもくもく会です。 kzrb.doorkeeper.jp

同日に富山でTDDBCが開催されていてそちらに行ってた人も多く、5人でもくもくしていましたw

プログラミングElixir

会場に行く前に本屋に寄りたまたま見つけたのが『プログラミングElixir』。 以前 @tyabe さんがElixirっていう言語があって気になるんですよねえと言っていて(確か)、当時はScalaをやるのに精一杯で全く見れていなかったんですが、Ruby風味な文法ということもありkanazawa.rbで触るのにも良さそうと思い即購入!

プログラミングElixir

プログラミングElixir

Macに環境を構築し、第5章までの内容を読みながら写経していました。

インストール

Mac OSXならばbrewでインストール可能です。また、Dockerイメージが用意されているのでこちらを使うのも良いかと思います。

$ brew install elixir

Installing Elixir - Elixir

インストールすると iex という対話型シェルが使えるので、これで様々なスクリプトを試していました。特に設定しなくとも名前の補完や結果の表示に色が付いていて、ナウくて優秀だなあと思いました。パターンマッチや無名関数の章を読みましたが、ScalaHaskellを触っていたのでこの辺はスッと入ってきました。また、全てが不変な値で扱われるという性質があるため、これも馴染みのある感じでした。

まだまだ基礎的な章なのでコード片しか書けてないですが、読み進めていろいろ書けるようになりたいです。

飲み会

Golangが使われ始めているという話から、プログラミング言語選定におけるRubyの優位性、プログラミング教育に使う言語(Pythonが圧倒的で最近はSwiftも力を入れてきている?)。あとはライフイベントとそれに伴って働き方どうするみたいなことを話したような気がします。酒が弱くなってたので、もうちょっと頑張りたいw

唐揚げ

豚タン煮込み

普通に原子時計が出てくる懐の深さ #kzrb

三次会 #kzrb

Akka Streamsでgzip圧縮されたテキストファイルを読み込んでデータを扱うサンプル

Akka Streamsのドキュメントをパラパラと見ていたら Dealing with compressed data streams という項目があって、なんか便利そうだなあと思ってサンプルコードを書いて試してみました。

Streams Cookbook — Akka Documentation

package sample

import java.nio.file.Paths

import akka.actor.ActorSystem
import akka.event.Logging
import akka.stream.{ActorMaterializer, Attributes}
import akka.stream.scaladsl._
import akka.util.ByteString

/**
  * Created by takayuki_atkwsk on 2017/02/05.
  */
object DecompressExample {

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem("decompress-example")
    implicit val materializer = ActorMaterializer()

    FileIO.fromPath(Paths.get("in.txt.gz"), 100) // ファイルから100バイトごと読み込む
      .log("compressed").withAttributes(Attributes.logLevels(onElement = Logging.InfoLevel))
      .via(Compression.gunzip()) // akka.stream.scaladsl.Compression
      .log("decompressed").withAttributes(Attributes.logLevels(onElement = Logging.InfoLevel))
      .map(_.utf8String)
      .map(_.toUpperCase)
      .map(ByteString.fromString) // FileIO.toPathに繋げるときはByteStringで渡す
      .to(FileIO.toPath(Paths.get("out.txt")))
      .run()
  }
}

テキストファイルをgzipした in.txt.gz を用意しておいて上記を実行すると out.txt に大文字になったテキストが出力されます。

Lorem ipsumを書いて圧縮したファイルを用意して実行するとログはこんな感じで吐かれます。

[INFO] [02/08/2017 20:44:36.092] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [compressed] Element: ByteString(31, -117, 8, 8, 36, 12, -105, 88, 0, 3, 104, 111, 103, 101, 46, 116, 120, 116, 0, 85, 83, 75, -118, -36, 64, 12, -35, -49, 41, 116, -128, -90, 111, -47, -112, 64, 2, 3, 33, -39, -53, 46, -75, 91, 80, 31, -113, -86, -28, 76, 114, -6, 60, -107, 103, -96, -77, -15, -62, -91, -49, -5, -23, 91, 51, 41, -92, 123, -9, 66, -87, -27, 102, -44, 117, 16, 23, 25, 23, 122, 115, -91, 71, 43, 98, -115, -122, -23, -32, -86, -108, 116, 21, -109, 65, -15, 124, 104, 39, -82)
[INFO] [02/08/2017 20:44:36.095] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [decompressed] Element: ByteString(76, 111, 114, 101, 109, 32, 105, 112, 115, 117, 109, 32, 100, 111, 108, 111, 114, 32, 115, 105, 116, 32, 97, 109, 101, 116, 44, 32, 113, 117, 105, 32, 104, 111, 109, 101, 114, 111, 32, 116, 114, 105, 116, 97, 110, 105, 32, 100, 105, 99, 101, 114, 101, 116, 32, 101, 116, 44, 32, 118, 105, 115, 32, 97, 110)
[INFO] [02/08/2017 20:44:36.096] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [compressed] Element: ByteString(36, -17, 98, -85, 18, -37, -26, 69, -22, -16, 114, -95, -38, -86, -105, 63, 81, 60, -72, -45, 46, 70, 85, -82, -12, 106, 74, -19, 126, -105, -102, -80, 1, 63, 117, -11, -116, 17, -30, 87, -6, -71, -24, -101, 11, -83, -83, 30, 82, -43, -124, -6, 106, -70, -60, 52, -61, 59, 61, -72, -57, -70, 119, 76, -20, -79, -97, -12, -77, 14, 29, 93, -122, 68, 29, -41, 11, -3, -42, -82, -12, -41, 52, 83, 102, 79, 32, -42, -123, 1, -16, 74, 55, 107, -99, -114, 103, 38, 111, -34)
[INFO] [02/08/2017 20:44:36.096] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [decompressed] Element: ByteString(32, 101, 120, 101, 114, 99, 105, 32, 97, 114, 103, 117, 109, 101, 110, 116, 117, 109, 44, 32, 110, 111, 110, 117, 109, 121, 32, 100, 105, 99, 116, 97, 115, 32, 112, 101, 114, 32, 110, 101, 46, 32, 80, 114, 105, 32, 111, 102, 102, 101, 110, 100, 105, 116, 32, 112, 101, 114, 105, 99, 117, 108, 105, 115, 32, 101, 117, 46, 32, 85, 98, 105, 113, 117, 101, 32, 99, 111, 110, 118, 101, 110, 105, 114, 101, 32, 115, 99, 114, 105, 98, 101, 110, 116, 117, 114, 32, 101, 117, 32)... and [86] more
[INFO] [02/08/2017 20:44:36.097] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [compressed] Element: ByteString(-120, -63, 34, -48, 29, 26, -112, 38, 125, -12, -84, 122, -24, -30, -63, -19, 74, 63, -128, 99, 31, 76, -100, 116, -57, 110, -83, -37, 19, 81, -88, 64, -107, -53, -11, -27, -27, -26, 84, -76, 106, -63, 84, -106, 96, 114, 23, -33, 24, 51, 37, -28, -24, 31, 67, -110, -36, 81, 36, 11, 7, -23, 2, -107, 46, -76, -6, -108, -79, -107, -118, 111, -26, 5, 0, 58, -108, 106, 61, 92, 48, -39, 77, -53, 84, -26, -127, 103, 5, -98, -17, 14, -11, -64, 122, -41, -42, 89, -94, 29)
[INFO] [02/08/2017 20:44:36.097] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [decompressed] Element: ByteString(111, 32, 97, 116, 44, 32, 112, 101, 114, 32, 118, 105, 100, 105, 116, 32, 100, 111, 108, 111, 114, 101, 109, 32, 99, 105, 118, 105, 98, 117, 115, 32, 97, 110, 46, 32, 83, 99, 114, 105, 112, 116, 97, 32, 97, 100, 105, 112, 105, 115, 99, 105, 110, 103, 32, 97, 114, 103, 117, 109, 101, 110, 116, 117, 109, 32, 101, 116, 32, 110, 97, 109, 46, 10, 10, 69, 117, 32, 109, 105, 110, 105, 109, 32, 113, 117, 97, 101, 113, 117, 101, 32, 102, 101, 117, 103, 97, 105, 116, 32)... and [98] more
[INFO] [02/08/2017 20:44:36.098] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [compressed] Element: ByteString(37, -105, 96, -90, 36, -8, 14, 37, 31, -42, -94, -91, -74, 120, 3, 5, 76, -38, -116, 101, -59, -120, -46, -78, -12, -95, -24, 60, 116, 56, -88, -13, -28, 118, 33, -127, 60, 24, 6, -47, -108, -53, 7, -48, -95, -83, -54, 100, -57, 51, 20, 107, 51, -13, -78, -1, 7, -20, 76, 65, -103, -88, -4, 52, -79, 84, -23, 108, -21, 99, -22, 115, -91, 95, 33, 122, -25, 125, -58, -90, 72, 6, -66, 8, 8, -90, -107, -46, 18, 60, -56, -24, -46, 61, -100, 28, 80, 53, 118, -10)
[INFO] [02/08/2017 20:44:36.098] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [decompressed] Element: ByteString(112, 114, 105, 44, 32, 118, 101, 114, 105, 32, 101, 118, 101, 114, 116, 105, 32, 117, 116, 114, 111, 113, 117, 101, 32, 110, 111, 32, 112, 114, 105, 46, 32, 83, 105, 116, 32, 103, 114, 97, 101, 99, 105, 115, 32, 109, 111, 108, 101, 115, 116, 105, 97, 101, 32, 118, 105, 116, 117, 112, 101, 114, 97, 116, 97, 32, 97, 100, 44, 32, 101, 111, 115, 32, 99, 117, 32, 97, 117, 100, 105, 97, 109, 32, 100, 101, 102, 105, 110, 105, 116, 105, 111, 110, 101, 109, 46, 10, 10, 69)... and [112] more
[INFO] [02/08/2017 20:44:36.098] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [compressed] Element: ByteString(19, -8, -51, -89, -25, 40, 80, 12, -128, 1, 83, 127, 56, -122, -127, -64, 90, -37, -126, -43, 80, 97, 23, 0, -50, 18, -128, 103, -109, -124, 17, -110, 117, -117, -92, -63, -29, 86, 26, 112, 99, 86, 112, 121, -123, -35, 120, 27, -92, 57, 123, -102, -36, -69, -108, 8, -63, 84, -97, 11, -116, -113, -48, 12, 80, 11, 121, -112, -118, 18, -82, 67, 91, 97, 3, -8, 32, 124, -118, 122, 120, -34, 125, -16, -128, -104, 45, 59, 12, 54, 101, -46, 20, 38, -83, 26, 99, -72, -82, 35)
[INFO] [02/08/2017 20:44:36.098] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [decompressed] Element: ByteString(32, 112, 114, 105, 46, 32, 69, 117, 32, 118, 105, 120, 32, 97, 108, 105, 105, 32, 115, 97, 100, 105, 112, 115, 99, 105, 110, 103, 44, 32, 112, 114, 111, 32, 99, 117, 32, 110, 111, 98, 105, 115, 32, 115, 97, 101, 112, 101, 32, 100, 101, 108, 101, 110, 105, 116, 105, 46, 32, 69, 117, 32, 101, 110, 105, 109, 32, 101, 108, 105, 103, 101, 110, 100, 105, 32, 97, 116, 111, 109, 111, 114, 117, 109, 32, 118, 105, 109, 46, 10, 10, 80, 101, 114, 32, 101, 108, 105, 116, 32)... and [103] more
[INFO] [02/08/2017 20:44:36.099] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [compressed] Element: ByteString(114, -12, -119, 0, 49, -98, 38, 126, 1, -18, -107, -69, 80, 91, -14, -108, 44, 75, 96, -123, 5, 2, 47, 59, 60, 2, 60, -88, -79, 33, -32, -56, -41, 60, -98, -101, 126, -58, -125, 30, -88, 53, 24, -114, 116, 49, -46, -123, 19, 60, -11, 127, -118, 11, -8, -32, -88, 112, -124, -92, -90, 30, -9, 36, -72, -109, 104, -87, -78, -50, -32, 33, -2, -119, 0, 30, 122, -97, -7, 60, -97, -67, 59, 40, -52, 92, 34, -111, 25, 96, 42, -64, 36, -127, -9, 18, 33, 9, 5, -35)
[INFO] [02/08/2017 20:44:36.099] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [decompressed] Element: ByteString(117, 115, 32, 97, 116, 111, 109, 111, 114, 117, 109, 32, 104, 97, 115, 32, 105, 110, 46, 32, 72, 105, 115, 32, 99, 97, 115, 101, 32, 111, 98, 108, 105, 113, 117, 101, 32, 108, 101, 103, 101, 110, 100, 111, 115, 32, 101, 105, 44, 32, 115, 111, 108, 101, 116, 32, 105, 110, 116, 101, 103, 114, 101, 32, 110, 97, 109, 32, 110, 101, 46, 32, 69, 105, 32, 108, 97, 98, 111, 114, 101, 115, 32, 104, 101, 110, 100, 114, 101, 114, 105, 116, 32, 101, 97, 109, 44, 32, 97, 110)... and [112] more
[INFO] [02/08/2017 20:44:36.099] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [compressed] Element: ByteString(-58, -109, 125, 41, 104, 77, 124, 9, 23, 117, -9, 13, 83, 70, 51, 28, -62, 104, -72, 90, 77, -28, 80, 26, 87, -11, 104, -16, -19, 89, 41, 71, -37, -49, -48, 51, 33, 52, -100, -89, 68, 90, -5, 48, 95, 1, -53, 34, -13, 87, -6, 90, 103, -20, 118, -88, -36, 117, -85, 122, 23, -108, 5, -59, -72, -96, 64, -22, 39, 104, -104, 9, -87, 31, -68, 8, 28, 60, -81, 26, 85, -123, -78, 46, 6, -71, 55, 95, -60, -96, 103, 13, -125, 94, -2, 1, -71, 19, 69, 70)
[INFO] [02/08/2017 20:44:36.100] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [decompressed] Element: ByteString(114, 116, 111, 32, 99, 111, 109, 109, 111, 100, 111, 32, 97, 100, 32, 104, 97, 115, 46, 32, 69, 105, 32, 100, 117, 111, 32, 102, 117, 103, 105, 116, 32, 116, 111, 114, 113, 117, 97, 116, 111, 115, 44, 32, 105, 100, 32, 117, 108, 108, 117, 109, 32, 99, 104, 111, 114, 111, 32, 118, 111, 108, 117, 112, 116, 97, 114, 105, 97, 32, 105, 117, 115, 46, 32, 85, 116, 32, 118, 105, 100, 101, 32, 109, 97, 108, 111, 114, 117, 109, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105)... and [93] more
[INFO] [02/08/2017 20:44:36.103] [decompress-example-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://decompress-example/user/StreamSupervisor-0)] [compressed] Element: ByteString(-11, 4, 0, 0)

ちょっと実戦的な使いどころが怪しげですが、gzip圧縮されたデータを扱う場合には役に立ちそうな感じです。

2016年個人的振り返り

毎年恒例の振り返り記事です。ついに5回目!

www.blogaomu.com

www.blogaomu.com

www.blogaomu.com

www.blogaomu.com

仕事

携わっているアプリが2015年の年末にリリースされ、2016年はいよいよ運用フェーズに入ったというのが環境としては一つ変わりました。前年のようにひたすら機能開発というよりもシステムの安定性、インフラ構成の最適化、機能の取捨選択、管理画面の充実、といったところがプロジェクトとしてはフォーカスされていたのかなと思います。個人の役割としては引き続きサーバーチームのマクロとミクロを見るような感じで、コードレビュワー、API仕様のまとめ、カスタマーサポートとの繋ぎ、AWS上のオペレーションなどなど相変わらずいろいろ顔を出しておりました。

また、働く環境としても変化があり、2016年の7月から東京から地元である金沢に戻ってリモートワークで働き始めました。そして10月からは所属していた会社の親会社からの離脱等があり個人事業主として契約形態を変えて働いております。

リモートワークについてはブログだったりLTだったりで出力したものがあるので興味があれば見てもらえるとありがたいです。働きやすいか?と問われれば働きやすいです。やはり毎日の通勤から解放されるのと環境の最適化がしやすい(作業部屋のレイアウトだったり、室温の調節だったり)というのが働きやすいと感じる大きな点です。

www.blogaomu.com

docs.google.com

このメインのお仕事の他に @ma_ogawa さんの携わっているサービスのCI環境を構築するお手伝いをさせていただきました。Bitbucket Pipelines + Docker + Packer + Ansible を使って構築しています。Packerをゴリゴリ使うのは初めて(試しに触ったことはあったが)で大変でしたが、よくできたツールだなあと改めて感心しました。

ところで、最近仕事をしていて思うようになったのは、自分で実装する時間が減りレビューをする時間が増えて自分がレビューしているときに自信が持てなくなる瞬間がある、ということです。そんなんじゃレビュワーの資格がないやろ、という指摘を受けそうですが。自分の経験と知識から導き出されるものについては迷いは生じないのですが、新しい概念が出てきたときに「あれっこれはこの方法でbetterなのかな?」っていうところに確証が持てないことがちょこちょこありました。こういうことがあったので個人開発したり勉強したりっていうのに時間を掛けたいなと思うようになりました。

コミュニティ活動

金沢に戻ってきたというのと普段はリモートで作業しているというのがあって金沢の技術者コミュニティに参加してみることにしました。主に Kanazawa.rb に参加していて常連さんになってきました。JAWS-JG 金沢にも1度参加してきました。こちらもちょこちょこ顔出せるようにしていきたいです。

東京に住んでいた頃は Shibuya.rb や Scala勉強会 in 東京に顔を出していましたが、金沢のコミュニティはハードウェアやってる人がそこそこいるなあというのが特徴的だなと思います。Kanazawa.rb のもくもく会でも基板持ってきてmruby組み込んでちょっとしたものを作る人もいて、これまでハードウェア系の人や組み込み系の人とあまり接点がなかったので一緒にもくもくして話すというのはとても刺激になっています。開発者の絶対的な人数は東京には敵いませんが、個々人ではレベル高い人もいるしジャンルも様々でおもしろいなという印象を受けています。(東京だと勉強会やコミュニティの細分化が進んでいて似たようなことをやっている人が集まりやすいのかもしれません)

私のやっていき

作業中に音楽やラジオを聴くことが多いのですが、やっていきfmというポッドキャストが最近おもしろくて良く聴いています。

yatteiki.fm

個人開発者が2人出てきて毎回1時間程度雑談するラジオなんですが、話されている内容にリアリティがあって共感できる部分が多いのが好んで聴いてる理由の一つなのかなあと思います。あと緩さもいいですね。仕事をやりつつ個人開発(もしくは類する活動)をやりつつ生活をやっていくという個人開発者のありのままの姿が垣間見れてみんなやっていってるんだなあ私もやっていこう、というような気持ちにさせてくれて刺激になってます。

だいたい既に書いてきている事ではありますが、足りないスキルを身に付けること、仕事におけるリソース配分、生活におけるリソース配分というところを意識して過ごしていきたいです。

去年の振り返り記事でこう過ごしていきたいと書いていたのですが、まさに仕事だけに偏らずに地に足のついた生活をしていきたいというテーマなのかなと思っていて2016年はその基盤を作れたのかなという気がしています。仕事してお金を稼いで、個人開発で作りたいものを作り知識を増やす、こういうものをベースに健康的に生活するというのを継続してやっていきたいですね。

プロフィールページを整えた

ひそかに自分のプロフィールページを用意しているのですが、2013年に雑に作ったまま魔放置していて味気ない感じになっていたので多少整備することにしました。

https://takayukiatkwsk.github.io

Pure

purecss.io

Yahooが公開しているPureというCSSライブラリがあって、レスポンシブなレイアウトを構成するのに必要なものが最低限用意されています。また、ファイルサイズの小ささ(公式によると3.7KB)というのが特徴です。1〜2年前から良さげと思って注目していながら使えずにいたのですが、2016年末にようやく使う機会が訪れました。

グリッド

まずグリッドを使ってレイアウトを整えました。手軽にグリッド使えるのいいですね。グリッド用のクラス pure-g とユニット(グリッド内の個々のコンテンツを格納するもの)用のクラス pure-u-* が用意されています。ユニットの幅は pure-u-** で指定することができて、 pure-u-1-2 であれば全体の1/2、pure-u-3-5 ならば3/5という風な命名規則となっていて分かりやすいです。

また、レスポンシブにすることも可能で、grids-responsive-min.css を追加で読み込みメディアクエリ用のクラスを指定します。下の例で言うと pure-u-md-2-5 というのが横幅 768px 以上のときに適用されてグリッド内で2/5の幅を使います。横幅が768pxより小さい場合は pure-u-1 が適用されてグリッド全体を占めるように表示されます。md の他にも幅を表すキーが用意されているのでメディアによって柔軟な表現をすることもできそうです。

以下にAbout meセクションのhtmlを挙げました。PCなんかで見た場合アイコン画像と文章が横並びで表示されますが、スマホから見た場合は縦並びで表示されます。

<div class="pure-g">
  <div class="pure-u-1 pure-u-md-2-5">
    <div class="inner-box">
      <img src="images/icon2.png" class="pure-img icon">
    </div>
  </div>
  <div class="pure-u-1 pure-u-md-3-5">
    <div class="inner-box">
      <p>TAKAyukiatkwsk(たかゆきあっとかわさき)です。にぼしという名前でも活動しています。</p>
      <p>1984年生まれ、金沢出身、東京在住のち金沢に戻ってきました。Webプログラマ、Scalaを主に使っています。Infrastructure as Code/数学が気になってます。</p>
      <p>ビール好き、猫を眺めていたい。フロンターレとツエーゲンとベガルタレディースを主に応援しています。</p>
    </div>
  </div>
</div>

Pureのグリッドシステムについて詳しくはこちらを参照してください。 purecss.io

メニュー

外部リンクのリストをどうしようかと思っていたのですが、Pureでメニューモジュールが用意されていたので使ってみることにしました。メニューが適切なのか?という話はあるかもしれませんが、使ってみたかったんや!ということで。pure-menu pure-menu-list pure-menu-item pure-menu-link というメニュー用のクラスが用意されています。これらのクラスを外側からよしなに指定してあげるとメニューができあがります。以下例です。menu-width クラスは自分で用意したもので、display: inline-block をひもづけています。メニューの幅をli要素内の文字列の幅に抑えるために指定しています。

<div class="pure-menu menu-width">
  <ul class="pure-menu-list">
    <li class="pure-menu-item"><a class="pure-menu-link" href="http://blogaomu21.blog91.fc2.com">Old blog</a></li>
    <li class="pure-menu-item"><a class="pure-menu-link" href="https://twitter.com/TAKAyuki_atkwsk">Twitter (@TAKAyuki_atkwsk)</a></li>
    <li class="pure-menu-item"><a class="pure-menu-link" href="https://github.com/TAKAyukiatkwsk">GitHub (@TAKAyukiatkwsk)</a></li>
    <li class="pure-menu-item"><a class="pure-menu-link" href="http://qiita.com/TAKAyuki_atkwsk">Qiita (TAKAyuki_atkwsk)</a></li>
    <li class="pure-menu-item"><a class="pure-menu-link" href="http://b.hatena.ne.jp/TAKAyuki_atkwsk/">はてなブックマーク (TAKAyuki_atkwsk)</a></li>
    <li class="pure-menu-item"><a class="pure-menu-link" href="http://amzn.asia/ewqSBdx">ほしい物リスト</a></li>
  </ul>
</div>

Pureのメニューについて詳しくはこちらを参照してください。 purecss.io

終わりに

今回はPureを使ってプロフィールページの表示を整えました。お手軽にグリッドを使いたいならばBootstrapよりもいいなあという気持ちです。修正前のページで計測するのを忘れていたので比較できないのですが、モバイルフレンドリーになっていました。 f:id:TAKAyuki_atkwsk:20161224140137p:plain

kanazawa.rb meetup #52 に参加しました #kzrb

早いもので今年最後のkanazawa.rbです。今回は締めくくりとしてLT大会が行われました。

Meetup #52 - Kanazawarb

お試し Bitbucket Pipelines

docs.google.com

今年の夏ぐらい(?)からBitbucket内でCIサービスが使えるようになりました。ビルド環境がDockerコンテナというのも今っぽいです。Bitbucket上でポチポチ触ってたらビルドが始まるのはグッとくるものがありますね。LT内でBitbucket上からPipelinesを有効にして最初のビルドを行うというデモをしたのですが、おおっという反応がありました。

最近のお仕事でBitbucket Pipelinesを使ってCI環境を整えるというものがあって、ここ1ヶ月ぐらいで初めて知っていろいろ調査していました。もう少し突っ込んだ話は別途ブログで書けたらなあと思ってます。

全体的な感想

12月ということもあって今年を振り返るLTが多かったですね。どの話も、私はこう思ったとかこういう気持ちになったとかいう主観が現れていて、聞いていて面白かったです。昨今のコピペ記事だったりエアインタビューあるいはコタツ記事だったりそういったものが蔓延っている風潮で辟易していたわけですが、自分で手を動かして体験してそれを噛み砕いて伝えるというのは、受け取り側としてはリアリティがあって面白みとか感じ方とか増幅するような感じがあります。そういうお話がおよそ20本あってこれはもう最高だな、と思ったのでした。私もそんなコンテンツを出し続けていきたいです。

その雰囲気を作っていた会場のDMM.com Labo 南町オフィス、いい環境でした。4枚分のディスプレイ(何インチになるのかな)で遠くからでも見やすいし、オープンスペースも広くて快適です。ここで仕事したーいと言ってた人も何人かいましたw

あとピザよいですね。ドミノピザのGPS DRIVER TRACKERという配達状況をGoogleMapにマッピングして可視化してくれるサービスがあって、これをピザが来るまでスクリーンに映してみんなで待ってたのはエンターテイメント性あって面白かったです。

kzrb でピザ祭り

来年もよろしくお願いします。

kanazawa.rb meetup #51 に参加しました #kzrb

Meetup #51 - Kanazawarb

kzrb.doorkeeper.jp

今回は参加者が多く(初参加の方もいた)、バックグラウンドも様々な人たちが集まっていました。基板持ってきて光や音を出したり、RubyやGoやElectron触ってたり、勉強してたりなど全体的に幅広いジャンルでもくもくしていました。 そんな中私はお仕事してたんですが(汗)諸々のパッケージをインストールする必要があったため社内共有用の手順をまとめる作業をしていました。

LTもいくつかあって、雑にまとめるとこんな感じ。

vim-adventures.com

RPG形式でVimの操作方法を学べるやつ。

gadget.renesas.com

mrubyでLチカや温度センサーの値を読むデモを行ってました。雑にばーっとコード書いて物理的なものが動くっていうのは取っ掛かりとしてはいいなあと思った。

github.com

yamlで書いたタスクリストを読み込んでGitHub Issueにしてくれるツール。それとともに勉強会等のイベントにおけるタスクの共有(フォークできると便利そう)だったり、運営の敷居を下げたいという気持ちの話が印象的だった。

k.swd.cc

上記のVim Adventuresに対抗して(?)、Gitのブランチについて学べるやつ。

yhatt.github.io

Markdown記法でスライドを作れるデスクトップアプリケーション。Electron製らしい。

次回はLT大会ですってよ!!なにしゃべろうかな( 'ω')