空飛ぶ羊

勉強したり登壇したり勉強会参加したり

職務経歴書をGitHubに公開するのはいいぞ #職務経歴書

この記事は松村Advent Calendarの19日目です。

www.adventar.org

登壇ネタは12/13までで終わったのでここからはノンジャンルでいきたいと思います。

本題

自分、売り込んでますか?

転職活動とは言わないけれど、自分を売り込んでいますか?エンジニアは売り手市場と言われていますが、それにいつまでも甘えてはいられません。私は実力の割にめっちゃ売り込んでいるつもりです。ちょっとした実績もWantedlyにめっちゃ反映しています。

www.wantedly.com

すると、WantedlyやFacebookメッセンジャー、Linkedin、GMailなどにかなりの頻度でスカウトがきます。スカウトされたら半分くらいは、会うようにしています。興味ある企業だったらいいんですが、案外話してたら面白い企業とかあったらもったいないので。

書類めんどくさい

でも、スカウトされた後返信するとよく言われるのは「履歴書と職務経歴書をください」いちいち書類かくの面倒ですし、こちらから志望したのではなく、向こうからスカウトなのであれば志望理由とか書けないし、でもとりあえず会ってみたい。
そんなときってないでしょうか。

そこで履歴書だったらWantedlyです。一般的な履歴書にある情報のうち住所以外が書いてあります。スタートアップだったりWeb系企業だとこれで問題ない時が最近多いです。
ただ、職務経歴書だけはなかったんですよね・・・

ないものは作る

だってエンジニアですからね。私は、職務経歴書GitHubでプレビューできるように職務経歴書リポジトリを作成して、それのREADME.mdに職務経歴をまとめました。また、他の人も利用できるようにテンプレートのリポジトリを作りました。ここにある内容書けばだいたい職務経歴書と同じ情報を提供できるでしょう。
github.com

これを作ったいきさつについての詳細はQiitaにまとめているのでそちらを御覧ください
qiita.com

まとめ

やるべきことに力を注ごう
エンジニアの本業は人と人とのやりとりをするためのドキュメントを書くことではなくものづくりのはずです。だから、そこに集中できるように他の部分はどんどん省いていきましょう。

おまけ

おまけが本番。Qiitaの記事についてTwitterはてブコメントでみつけた疑問とか意見にここで答える。

Q:OSSというか「GitHubに置いた」が正しいのではないか

その通りです。そのため、テンプレートにはCC0のライセンスを設置しています。ご自身の職務経歴書については自分で考えてくださいw

意見:MasterにPushするとCIでPagesのブランチにHTMLとして書き出すところまでやるとすごく良さそう

今はdocsで同じブランチに管理もできるようにもなりましたし、良さそうですね!

Q:フォーマットはMarkdown, JSON, yamlのどれがいいんだ

私はMarkdownがいいと思います。JSONyamlだと同じ会社でいろんなプロジェクトでいろんな仕事をしていた場合に階層が深くなってしまうと思います。

意見:自分では思っていない良い点がPRで来るので社内の人事査定版みたいなのもあっていい話だ

導入したら教えてください!

Q:便利そうだけど、いままでの職歴フルオープンにしても大丈夫なのかな…

それは職歴次第です。NDA・企業秘密は守りましょう。

意見:linkedinでいいのでは

日本だとそんなにlinkedin流行ってないのでGitHubのほうがいいと思いました。

意見:企業の人事の履歴が企業間で共通のフォーマットになっていていつでもダウンロード可能になってればいいんだろうな、とは思った。

それな!それだったら毎回作成する必要もないですし。

意見:経歴詐称すると同級生とか元上司とかからPR来るのか。

来ます。それはそれで面白いかと思います。

明日は12/17にあったMashup Awards for Proの決勝について私が書きます。

業務外でもScalaは伸ばせる #Scala

この記事はdots.女子部 Advent Calendar 2016の18日目です。
昨日は私のQiitaの軽くバズった記事にコメントしてくださったTamilyさんです。

qiita.com

この記事について

業務でScalaがやれなくて何やれば良いのかわからない人でも、業務外でScalaのスキル上げられるっていう話をします。ただ、Scalaに限っていないので他の言語でも参考になると思います。

本題の前に

昨日はMashup Awardsのfor Pro部門決勝戦がありました。結果は優勝!!!初代チャンピオンになりました。やったぜ!
okoysm.hatenablog.jp

本題

TL;DR

伸ばしたいスキルがあれば「師匠(Sensei)」を見つけよう!

Scalaできるようになりたいけど・・・

私はScalaがやりたくてちょっと触ったり、コップ本買ったりしてました。でも分かんないんです、何から手を付ければ。しかも、その書いたコードがどれだけのレベルなのか。Scalaの良いところをつかえているのか・・・

初心者が行けそうな勉強会が少ない・・・

Scalaの勉強会って圧倒的に少ないし、あったとしても参加者みると「あ、あのヤバイ人だ」ってなって、なかなかいけませんでした。この前やっと初めてScala勉強会行きました。とても和やかな雰囲気でしたが、やっぱりレベルの高い人ばかりでした。自分はここに居ていいのだろうかという感じにもなりました。

自信つけるしかないしスキルあげよう!

でも、いつまでも自信がないままでも駄目なのでスキルを粛々と上げています。現在はGitHubでstudy-scalaというリポジトリを公開し、そこに勉強して書いたコードをアップロードしています。でも、書いただけじゃうまくなりませんよね。そこでコードレビューです。

業務外レビュワーを見つけよう!

私はTwitterで以下のように呼びかけてみました。

スクリーンショット 2016-12-06 0.21.23.png

すると @kmizu さんが手を挙げてくださいました。現在色々基本的なところから見ていただいています。本当に感謝しています。ありがとうございます。業務だったら上司だったり同僚がコードレビューしますが、業務外だとコードレビューなかなかしませんからね。SNSを使って先生を見つけましょう!

できれば英語で書こう!

少なくともこのリポジトリでは、日本語は日本人しか読めないのでやりたいことや何を考えてるかは基本的に英語で書いています。

まとめ

伸ばしたいスキルがあれば「師匠(Sensei)」を見つけよう!

明日の担当はyuunaさんです。楽しみー!

Mashup Awards優勝したぞおおおおお #MA_2016

興奮を書くだけ

Mashup Awards for Pro優勝したぞおおおおおおお

f:id:okoysm:20161217234744j:plain

発表資料

speakerdeck.com

togetter

togetter.com

審査員からの総評

イデアや仕組み自体は既存でもありましたが、それをストーリーを作って文脈があったこと、構成力が評価されました 審査コメントとしてあがったのは「あるまじき力のかけ方である」というフレーズでした、ぐるなびさんの素晴らしさがわかりました。おめでとうございます。

やったあああああああああああああ!

明日に向けての意気込み #MA_2016

明日はついにMashup Awards for Pro決勝戦!しかも初の360度ステージでのプレゼン!
ドキドキとわくわくが止まりません!

私たちの作品

「全社員早押上司争奪戦」です! hacklog.jp

デモ展示やります!

11:00〜14:00に会場内でデモ展示やります!発表前に触ってみたい方是非お越しください! 当日は限定ポストカードも配布予定です!

発表はfor Proの最後!

決勝は15:10から開始予定で私たちは最後です。 チームメンバー全員登壇します。

意気込み

狙うはもちろんfor Pro優勝です!

いいかお前らー! 私たちは逃げも隠れもしないぞー! 360度? 上等だ! 私たちの覚悟をしっかりと受け止めろー!

ちなみにこの言葉の元ネタはももいろクローバーZのしおりんの最初の言葉です。私の今の気持ちそのままなので引用しました!

ももクロ春の一大事2012~見渡せば大パノラマ地獄~ [DVD]

ももクロ春の一大事2012~見渡せば大パノラマ地獄~ [DVD]

どうやったら見に行ける?

下のDoorkeeper リンクから登録してください! 様々な作品があるので、2000円の価値はあるとおもいます! 是非お越しください!そして応援してください!

mashupawards.doorkeeper.jp

学習メモ: クラス (1/2) #dwango #Scala

この記事について

ドワンゴScala研修テキストを学習したときのメモです。 okoysm.hatenablog.jp

DOING

クラス

クラス定義

  • 記述方法以外はJavaと同じ (パラメータの指定方法くらい?)
class ClassName(parameter1: Type1, parameter2: Type2, ...) {
  (a field or method definition)の0回以上の繰り返し
}

例)点を表すクラスを定義する場合

class Point(_x: Int, _y: Int) {
  val x = _x
  val y = _y
}

コンストラクタの引数をそのまま公開したい場合は以下のように短く書ける

class Point(val x: Int, val y: Int)

疑問点

使うからクラスを定義するんだろうし、そのまま公開するケースのほうが多い気がしたのだけどどうなのだろう?

ポイント

この書き方のポイントは大きく2点。

  • クラス名の直後にコンストラクタの定義がある
    • Scalaでは1クラスに付き、基本的には1つのコンストラクタしか使わない
    • 文法上は複数のコンストラクタを定義できるようになっていますが、実際に使うことはまずないので覚える必要はない
    • 最初の1つのコンストラクタをプライマリコンストラクタとして特別に扱っている
  • val/varによって、コンストラクタ引数をフィールドとして公開することができる
    • プライマリコンストラクタの引数にval/varをつけるとそのフィールドは公開され、外部からアクセスできるようになる
    • コンストラクタ引数のスコープはクラス定義全体におよびます。

これを使うと、メソッド定義の中から直接コンストラクタ引数を参照できる。
このプログラムの場合+メソッド定義の中から直接コンストラクタ引数を参照している

class Point(val x: Int, val y: Int) {
  def +(p: Point): Point = {
    new Point(x + p.x, y + p.y)
  }
  override def toString(): String = "(" + x + ", " + y + ")"
}

この章での疑問点

  • コンストラクタの引数をそのまま公開したくない場合などあるのだろうか(Javaでいうprivateな変数にしてgetter/setterで取らせたいみたいなやつかな)

進捗

DONE

DOING

  • クラス

TODO

  • オブジェクト
  • トレイト
  • 型パラメータと変位指定
  • 関数
  • Scalaのコレクションライブラリ
  • ケースクラスとパターンマッチング
  • エラー処理
  • Implicit
  • 型クラスの紹介
  • FutureとPromise
  • テスト
  • Javaとの相互運用
  • S99の案内
  • トレイトの応用編:依存性の注入によるリファクタリング

学習メモ:Scalaの制御構文 #Scala #dwango

この記事について

ドワンゴScala研修テキストを学習した時のメモです。

okoysm.hatenablog.jp

DOING

Scalaの制御構文

言葉の定義

ScalaはCやJavaなどの手続き型の言語に比べて、文よりも式になる構文が多いため、変数などの状態をできるだけ排除したわかりやすいコードが書きやすい。

構文 (Syntax)

  • そのプログラミング言語内でプログラムが構造を持つためのルール
    • プログラミング言語内で特別扱いされるキーワード(class, val, ifなど)
    • 正しいプログラムを国姓するためのルール(クラスの中身は{}で括られる)

式 (Expression)

  • プログラムを構成する部分のうち、評価することで値になるもの
    • 11+2は数値になり、"hoge"は文字列の値になる

文 (Statement)

  • プログラムを構成する部分のうち、評価しても値にならないもの(⇔式(Expression))
    • val i = 1は、定義全体としては値を持たない。(変数iは定義され,iの値は1になるけれど)

{}式

  • {}構文の一般形は {exp1; exp2; ... expN; }
  • ;は改行で区切られていれば省略できる。
  • exp1からexpNを順番に評価し、expNを評価した値を返す。

Scalaにおける一般的なメソッド定義

scala > def foo(): String = {
  "foo" + "foo"
}

if式

Javaとほぼ同じだったのでスキップ

練習問題

var age: Int = 5という年齢を定義する変数とvar isSchoolStarted: Boolean = falseという就学を開始しているかどうかという変数を利用して、 1歳から6歳までの就学以前の子どもの場合に“幼児です”と出力し、それ以外の場合は“幼児ではありません”と出力するコードを書いてみましょう。

自分の回答

var age: Int = 5
var isSchoolStarted: Boolean = false

if(1 <= age && 6 <= age && !isSchoolStarted){println("幼児です")}else{println("未熟児です")}

while式

Javaとほぼ同じだったのでスキップ

練習問題

do whileを利用して、0から数え上げて9まで出力して10になったらループを終了するメソッドloopFrom0To9を書いてみましょう。loopFrom0To9は次のような形になります。???の部分を埋めてください。

def loopFrom0To9(): Unit = {
  var i = ???
  do {
    ???
  } while(???)
}

自分の回答

i++みたいなのってScala使えないんですね・・・

def loopFrom0To9(): Unit = {
  var i = 0
  do {
    println(i)
    i += 1
  } while(i < 10)
}

for式

Javaの制御構文と似た使い方ができるものの、全く異なる構文です。for式の本当の力を理解するには、flatMap, map, withFilter, foreachといったメソッドについて知る必要がありますが、ここでは基本的なfor式の使い方のみを説明します。

とあるので、心してかかりたいと思います。

基本的な構文

for(ジェネレータ1;  ジェネレータ2; ... ジェネレータn) A
# ジェネレータ1 = a1 <- exp1; ジェネレータ2 = a2 <- exp2; ... ジェネレータn = an <- expn
  • ジェネレータって言ってるのが条件っぽい(a1 <- exp1など)
  • exp1〜expnには、ある数の範囲を表す式を使える
    • 1 to 10→1から10まで (10を含む)
    • 1 until 10 →1から10まで (10を含まない)
scala> for(x <- 1 to 5; y <- 1 until 5){
         println("x = " + x + " y = " + y)
       }
x = 1 y = 1
x = 1 y = 2
x = 1 y = 3
x = 1 y = 4
x = 2 y = 1
x = 2 y = 2
x = 2 y = 3
x = 2 y = 4
x = 3 y = 1
x = 3 y = 2
x = 3 y = 3
x = 3 y = 4
x = 4 y = 1
x = 4 y = 2
x = 4 y = 3
x = 4 y = 4
x = 5 y = 1
x = 5 y = 2
x = 5 y = 3
x = 5 y = 4

ループ変数の中から条件にあったものだけを絞りこめる

以下の例だと x!=y が追加されたことによってx, y同じ値のものが表示されなくなっています。

scala> for(x <- 1 to 5; y <- 1 until 5 if x != y){
         println("x = " + x + " y = " + y)
       }
x = 1 y = 2
x = 1 y = 3
x = 1 y = 4
x = 2 y = 1
x = 2 y = 3
x = 2 y = 4
x = 3 y = 1
x = 3 y = 2
x = 3 y = 4
x = 4 y = 1
x = 4 y = 2
x = 4 y = 3
x = 5 y = 1
x = 5 y = 2
x = 5 y = 3
x = 5 y = 4

コレクションの要素を1つ1つ辿って処理を行うために使うことも可能

例えばListの中身の文字列をすべて出力する処理

scala> for(e <- List("A", "B", "C", "D", "E")) println(e)
A
B
C
D
E

コレクションの要素を辿って、加工して新しいコレクションを作成できる

この場合ジェネレータで指定したリストの要素の前にPreが付いた要素を持つリストが新しく作成されています。

scala> for(e <- List("A", "B", "C", "D", "E")) yield {
     |   "Pre" + e
     | }
res9: List[String] = List(PreA, PreB, PreC, PreD, PreE)

yieldキーワードを使ったfor式はfor式ではない

  • for-comprehensionと呼ぶ事がある
  • yieldキーワードを使うことで、コレクションの要素を加工して返すという異なる用途に使える

練習問題

1から1000までの3つの整数a, b, cについて、三辺からなる三角形が直角三角形になるような a, b, cの組み合わせを全て出力してください。直角三角形の条件にはピタゴラスの定理を利用してください。 ピタゴラスの定理とは三平方の定理とも呼ばれ、a ^ 2 == b ^ 2 + c ^ 2を満たす、a, b, c の長さの三辺を持つ三角形は、直角三角形になるというものです。

自分の回答

^が使えなくて微妙にハマった・・・

for (a <- 1 to 1000; b <- 1 to 1000; c <- 1 to 1000) if (a * a == b * b + c * c) {
  println("a=" + a + ", b=" + b + ", c=" + c)
}

模範解答と違ったところ

for文の中にif文を入れ込むかfor文とif文を分けるか。 模範解答はfor (a <- 1 to 1000; b <- 1 to 1000; c <- 1 to 1000 if a * a == b * b + c * c)
自分の回答はfor (a <- 1 to 1000; b <- 1 to 1000; c <- 1 to 1000) if (a * a == b * b + c * c)

match式

match式は使い方によって非常に幅のある制御構造です

基本構文

  • Javaのswitch-caseみたいなやつ
  • Scalaはbreakしなくていい(フォールスルー動作がない)
  • _はdefaultのようなもの(ワイルドカードパターン)
    • match式を使う際は漏れがないように、ワイルドカードパターンを利用することが多い。
マッチ対象の式 match {
  case パターン1 [if ガード1] => 式1
  case パターン2 [if ガード2] => 式2
  case パターン3 [if ガード3] => 式3
  case ...
  case パターンN => 式N
  case _       => "nothing"
}

パターンをまとめる

Javaのswitch-caseのときはフォールスルーさせていたけど、Scalaの場合はOR(|)でつなげられる。

"abc" match {
  case "abc" | "def" =>
    println("first")
    println("second")
}

パターンマッチによる値の取り出し

switch-case以外の使い方として、コレクションの要素の一部にマッチさせる使い方もある。
下の場合、「リストの先頭要素が"A"で5要素」のパターンにマッチすると残りが表示され、しなければ"nothing"が表示される。

scala> val lst = List("A", "B", "C", "D", "E")
lst: List[String] = List(A, B, C, D, E)

scala> lst match {
     |   case List("A", b, c, d, e) =>
     |     println("b = " + b)
     |     println("c = " + c)
     |     println("d = " + d)
     |     println("e = " + e)
     |   case _ =>
     |     println("nothing")
     | }
b = B
c = C
d = D
e = E

+ガード式なパターンマッチもできる

さっきのプログラムにガード式(今回の場合if b != "B")を追加すると"nothing"が表示されるようになる。

scala> val lst = List("A", "B", "C", "D", "E")
lst: List[String] = List(A, B, C, D, E)

scala> lst match {
     |   case List("A", b, c, d, e) if b != "B" =>
     |     println("b = " + b)
     |     println("c = " + c)
     |     println("d = " + d)
     |     println("e = " + e)
     |   case _ =>
     |     println("nothing")
     | }
nothing

パターンマッチのパターンのネストが可能

  • Listを要素として持つListをパターンマッチすることもできる
  • パターンの前に@がついているのはasパターンと呼ぶ
    • @の後に続くパターンにマッチする式を@の前の変数(今回の場合a)に束縛する。
  • このプログラムの場合パラメータがListで先頭要素がList("A")で2要素もつ場合matchし、List(A)ともう一つの要素が表示されている
scala> val lst = List(List("A"), List("B", "C", "D", "E"))
lst: List[List[String]] = List(List(A), List(B, C, D, E))

scala> lst match {
     |   case List(a@List("A"), x) =>
     |   println(a)
     |   println(x)
     |   case _ => println("nothing")
     | }
List(A)
List(B, C, D, E)

パターンマッチの場合、値をとりだすことはできない

  • パターンマッチで使った変数を使った場合、コンパイルエラーになる。
  • 下のerror patternの場合変数aを指定しているためコンパイルエラーになる
scala> (List("a"): Any) match {
     |   case List(a) | Some(a) =>
     |     println(a)
     | }
<console>:14: error: illegal variable in pattern alternative
         case List(a) | Some(a) =>
                   ^
<console>:14: error: illegal variable in pattern alternative
         case List(a) | Some(a) =>
                             ^

値を取り出さないパターンマッチは可能。ただこれいつ使うんだろう。型を見たい時とかだろうか・・・

(List("a"): Any) match {
  case List(_) | Some(_) =>
    println("ok")
}

型によるパターンマッチ

  • Scalaではcaseに値ではなく型を指定することも可能
  • 特定の型に所属する場合にのみマッチするパターンは名前:マッチする型と書く
  • AnyRef=JavaでいうObject型(なんでも格納できる)
  • 例外処理やequalsの定義などで使うことがある
  • しばしばキャストの代わりにパターンマッチが用いられるので覚えておくこと

このプログラムの場合AnyRefがStringにマッチしているので、すべてを大文字にした結果が表示されています。

scala> import java.util.Locale
import java.util.Locale

scala> val obj: AnyRef = "String Literal"
obj: AnyRef = String Literal

scala> obj match {
     |   case v:java.lang.Integer =>
     |     println("Integer!")
     |   case v:String =>
     |     println(v.toUpperCase(Locale.ENGLISH))
     | }
STRING LITERAL

JVMの制約による型のパターンマッチの落とし穴

  • 型変数を使った場合、正しくパターンマッチが行われない。
  • このプログラムだとcaseにList[Int]とList[String]を書いているが、パターンマッチでは区別できない
    • このプログラムの場合Scalaコンパイラの「型消去」という動作によりIntの部分が消され、ListであればすべてList[Int]に到達してしまう
scala> val obj: Any = List("a")
obj: Any = List(a)

scala> obj match {
     |   case v: List[Int]    => println("List[Int]")
     |   case v: List[String] => println("List[String]")
     | }
<console>:16: warning: non-variable type argument Int in type pattern List[Int] (the underlying of List[Int]) is unchecked since it is eliminated by erasure
         case v: List[Int]    => println("List[Int]")
                 ^
<console>:17: warning: non-variable type argument String in type pattern List[String] (the underlying of List[String]) is unchecked since it is eliminated by erasure
         case v: List[String] => println("List[String]")
                 ^
<console>:17: warning: unreachable code
         case v: List[String] => println("List[String]")
                                        ^
List[Int]

型変数を含む方のパターンマッチはワイルドカードパターンを使うと良い

obj match {
  case v: List[_] => println("List[_]")
}

練習問題

new scala.util.Random(new java.security.SecureRandom()).alphanumeric.take(5).toList

以上のコードを利用して、 最初と最後の文字が同じ英数字であるランダムな5文字の文字列を1000回出力してください。 new scala.util.Random(new java.security.SecureRandom()).alphanumeric.take(5).toListという値は、呼びだす度にランダムな5個の文字(Char型)のリストを与えます。なお、以上のコードで生成されたリストの一部分を利用するだけでよく、最初と最後の文字が同じ英数字であるリストになるまで試行を続ける必要はありません。これは、List(a, b, d, e, f)が得られた場合に、List(a, b, d, e, a)のようにしても良いということです。

自分の回答

うまくいかずギブアップ・・・

var i = 0

while(i <= 1000){
  val lst: List[Char] = new scala.util.Random(new java.security.SecureRandom()).alphanumeric.take(5).toList

  lst match {
    case List(a, b, c, d, e) if a == e =>
      i += 1
      println(lst)
  }
}
  

模範解答

問題文の

なお、以上のコードで生成されたリストの一部分を利用するだけでよく、最初と最後の文字が同じ英数字であるリストになるまで試行を続ける必要はありません。これは、List(a, b, d, e, f)が得られた場合に、List(a, b, d, e, a)のようにしても良いということです。

これを実装すると実にすっきりします。あとforかwhileどっちで回すといいとかあるのかな。

for(i <- 1 to 1000) {
  val s = new scala.util.Random(new java.security.SecureRandom()).alphanumeric.take(5).toList match {
    case List(a,b,c,d,_) => List(a,b,c,d,a).mkString
  }
  println(s)
}

この章での疑問点

if文の順序

age => 1 && age <=6 && !isSchoolStartedだとNGで
1 <= age && 6 <= age && !isSchoolStartedだとコンパイルが通るのはなぜだろうか・・・

値を取り出さないパターンマッチの使い所

  • 値を取り出さないパターンマッチは可能なのはわかったけど、これいつ使うんだろう。

進捗

DONE

TODO

  • クラス
  • オブジェクト
  • トレイト
  • 型パラメータと変位指定
  • 関数
  • Scalaのコレクションライブラリ
  • ケースクラスとパターンマッチング
  • エラー処理
  • Implicit
  • 型クラスの紹介
  • FutureとPromise
  • テスト
  • Javaとの相互運用
  • S99の案内
  • トレイトの応用編:依存性の注入によるリファクタリング

次回はクラスをやります。次回はいつだろう・・・年内にドワンゴテキスト終わらせたい。

ドワンゴScala研修テキスト学習中 #dwango #scala

一年くらい前にやったのだけど完全に忘れていたので再度開始

教材

ドワンゴScala研修テキスト
Introduction · Scala研修テキスト

進捗

DONE

TODO

  • Scalaの制御構文
  • クラス
  • オブジェクト
  • トレイト
  • 型パラメータと変位指定
  • 関数
  • Scalaのコレクションライブラリ
  • ケースクラスとパターンマッチング
  • エラー処理
  • Implicit
  • 型クラスの紹介
  • FutureとPromise
  • テスト
  • Javaとの相互運用
  • S99の案内
  • トレイトの応用編:依存性の注入によるリファクタリング