Scala入門者向けハンズオンに参加した #ScalaNyumon
1週間前ですが・・・
6月5日(土)はScala入門者向けハンズオン@東京に行くことが出来たー!
講師は@gakuzzzzさん!
資料は@mike_neckさんの!
github.com
豪華٩(๑❛ᴗ❛๑)۶
いっぱい知見を得たのでまとめた!(何故かうまくembedできない…)
http://togetter.com/li/986758/togetter.com
最初にScalaについてご説明があって、そのあとは簡単なチケット管理システムを作るハンズオン。
ということでブログにはハンズオンのことをさらっと書いておきたい。
こんな流れ↓で進めてくださり、最後、チケットの検索や更新をするTicketRepo
に自力でメソッドを追加してみよう〜というものだった!
カリキュラム · mike-neck/scala-study Wiki · GitHub
メソッドの仕様もここにあります。それにしても資料、丁寧・・・
私もTicketRepo
の中身を書いてみたものの怪しい実装だらけになったので、
みけさんの実装と比べてみようと思う。
- 私(以下🐳)の:
hello-scala/TicketRepo.scala at blog · ihcomega56/hello-scala · GitHub - みけさん(以下🐱)の *1 :
scala-study/TicketRepo.scala at master · ihcomega56/scala-study · GitHub
※私のはチケットをつっこむMapの名前がtickets
で、みけさんのはmap
なので以下のコードたちもそこの違いはあり〼
findAll: Seq[Ticket]
- 🐳こう書いてみた。
def findAll: Seq[Ticket] = {
tickets.values.toSeq
}
- 🐱IDでソートしてあった・・・親切・・・
def findAll(): Seq[Ticket] = {
map.values.toSeq.sortBy(_.id)
}
findById(id: TicketId): Option[Ticket]
- 🐳🐱同じだった。
def findById(id: TicketId): Option[Ticket] = { tickets.get(id) }
createIssue(title: String): Issue, createBug(title: String): Bug
※createIssue
は割愛
- 🐳自信なさげにこう書いた。
currentId
という怪しい変数、最悪っぽい…。
def createIssue(title: String): Issue = { val newIssue = new Issue(currentId, title) tickets = tickets + (currentId -> newIssue) currentId += 1 newIssue }
- 🐱こうやれば
currentId
いらないね。あとIssue
はcase class
なのでnew
しなくてよかった、あちゃ。
def createIssue(title: String): Issue = { val nextId: TicketId = if (map.isEmpty) 0 else map.keys.max + 1 val issue: Issue = Issue(nextId, title) map = map + (nextId -> issue) issue }
findIssuesByStatus(staus: String): Option[Seq[Issue]], findBugsByStatus(status: String): Option[Seq[Bug]]
※findBugsByStatus
は割愛
- 🐳空の
Seq
を返す術しか分からなくて最後に苦し紛れの一文を入れた('_')ちーん
def findIssuesByStatus(status: String): Option[Seq[Issue]] = { val issues = tickets.collect { case (id, ticket: Issue) if TicketStatus.isMatchedStatus(status, ticket) => ticket }.toSeq if (issues.nonEmpty) Some(issues) else None }
ちなみにTicketStatus.scala
にもメソッドを追加してある。
def isMatchedStatus(status: String, ticket: Ticket) = { status match { case "open" => ticket.status == TicketStatus.Open case "fixed" => ticket.status == TicketStatus.Fixed case _ => false } }
- 🐱ぎょーなんかシンプルだ。
def findIssuesByStatus(status: String): Option[Seq[Issue]] = { val st: Option[TicketStatus] = TicketStatus.of(status) st.map(s => { map.values.toSeq collect { case x: Issue if x.status == s => x } }) }
TicketStatus.scala
のメソッド〜。そもそもここの戻り値がOption
なのねそうなのね。
def of(status: String): Option[TicketStatus] = { status.toLowerCase match { case "open" => Option(Open) case "fixed" => Option(Fixed) case _ => None } }
fix(id: TicketId): Boolean
- 🐳ひどいよ〜(;▽;)
else return false
なんて書きたくないよ〜(;▽;)
def fix(id: TicketId): Boolean = { findById(id) match { case Some(t: Issue) => if (t.status == TicketStatus.Open) tickets = tickets.updated(id, new Issue(t.id, t.title, TicketStatus.Fixed)) else return false case Some(t: Bug) => if (t.status == TicketStatus.Open) tickets = tickets.updated(id, new Bug(t.id, t.title, t.description, TicketStatus.Fixed)) else return false case _ => return false } true }
- 🐱あ。あ。
exists
でチェックすればいいのだ。
def fix(id: TicketId): Boolean = { val ticket: Option[Ticket] = map.values.find(t => t.id == id && t.status == Open) ticket.exists(t => { map = map.updated(t.id, t match { case x: Issue => Issue(x.id, x.title, Fixed) case x: Bug => Bug(x.id, x.title, x.description, Fixed) }) true }) }
修行あるのみ✋(--)👌
最後にしょーもない感想。
今まで、既に動いてるシステムの改修しかしたことなかったので
trait
作って、object
でenum作って、case class
作って・・・って
新規作成の流れを体験できたのはとても勉強になったー。
あとはpackage object
とかsealed
とか知らなかったりよく分かってなかったりしたことも理解できてよかったなー。
学び多きイベントをありがとうございました!
*1:forkしました