rspecによるBDD

rspec install

[vagrant@localhost rspec]$ gem install rspec
[vagrant@localhost rspec]$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
[vagrant@localhost rspec]$ rspec -v
3.5.4

TDD/BDD 開発サイクル
1.失敗するテストを書く(Red)
2.最小限のコードを書いてテストをパスさせる(Green)
3.リファクタリング

initフォルダの作成

[vagrant@localhost rspec]$ rspec --init
  create   .rspec
  create   spec/spec_helper.rb

テストファイルは〇〇_spec.rbとし、specフォルダの中に書きます。

1.ミスするコード

RSpec.describe "A calc" do
  it "given 2 and 3, return 5" do
    calc = Calc.new
    epect(calc.add(2, 3)).to eq(5)
  end
end
[vagrant@localhost rspec]$ rspec
F

Failures:

  1) A calc given 2 and 3, return 5
     Failure/Error: calc = Calc.new

     NameError:
       uninitialized constant Calc
     # ./spec/calc_spec.rb:3:in `block (2 levels) in '

Finished in 0.00317 seconds (files took 0.32741 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/calc_spec.rb:2 # A calc given 2 and 3, return 5

2.パスするコードを作成

class Calc
  def add(a, b)
    5 # 仮実装
  end
end
require 'calc'

RSpec.describe "A calc" do
  it "given 2 and 3, returns 5" do
    calc = Calc.new
    expect(calc.add(2, 3)).to eq(5)
  end
end

実行

[vagrant@localhost rspec]$ rspec
.

Finished in 0.00095 seconds (files took 0.10059 seconds to load)
1 example, 0 failures

flexbox

cssのdisplayをflexとし、幅の比率や順番を簡単に記述することができます。

.container {
	width: 300px;
	height: 300px;
	color: #fff;
	background: #eee;
	display: flex;
	/*flex-direction:column-reverse;*/
	/*flex-wrap: wrap;*/
	/*flex-wrap: wrap-reverse;*/
	/*flex-flow: wrap column;*/
	/*justify-content: flex-start;*/
	/*justify-content: flex-end;*/
	/*justify-content: space-between;*/
	/*justify-content: space-around;*/
	/*align-items: flex-start;*/
	/*align-items: flex-end;*/
	/*align-items: flex-center;*/
	/*align-items: stretch;*/
	/*align-content: flex-start;*/
	/*align-content: space-between;*/
	/*align-content: space-around;*/
	justify-content: center;
	align-items: center;

}
.box {
	width:80px;
	height: 80px;
}
/*
flex-grow, shrink, basis, 
margin:auto;
*/
.box-1 { background: tomato; 
	/*flex: 0 1 120px;*/
	/*order: 1;
	align-self: flex-end;*/}
/*.box-2 { background: slategray;
	/*flex: 0 2 120px;*/ }*/
/*.box-3 { background: pink;
	margin-left: auto;
	/*flex: 0 3 120px;*/ }*/

Kotlin 構文2

getter, setter

class User(var name: String){
  var team = "red"
  get(){
    return field.toUpperCase()
  }

  set(value){
    if (value !=""){
      field = value
    }
  }

  fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val tom = User("tom")
  println(tom.team)
  tom.sayHi()
}

class override

class AdminUser(name: String): User(name){
  fun sayHello(){
    println("hello $name")
  }
  override fun sayHi(){
    println("what $name")
  }
}
open class User(var name: String){
  open fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val bob = AdminUser("bob")
  println(bob.name)
  bob.sayHi()
}

アクセス修飾子: privateとpublic

open class User(private var name: String){
  open fun sayHi(){
    println("hi $name")
  }
}

class extension

fun User.sayHello(){
  println("hello $name")
}

val User.myName: String
 get() = "I am $name"

class User(var name: String){
  open fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val bob = User("bob")
  bob.sayHello()
  bob.sayHi()
  println(bob.myName)
}

抽象クラス

abstract class User {
  abstract fun sayHi()
}
class Japanese: User(){
  override fun sayHi(){
    println("こんにちは")
  }
}
class American: User(){
  override fun sayHi(){
    println("hi")
  }
}

fun main(args: Array<String>){
  val tom = American()
  val taro = Japanese()
  tom.sayHi()
  taro.sayHi()
}

interface

interface Sharable{
  // 抽象プロパティ、抽象メソッド、メソッド
  val version: Double
  fun share()
  fun getInfo(){
    println("Share I/F ($version)")
  }
}
class User: Sharable {
  override val version = 1.1
  override fun share(){
    println("Sharing..")
  }
}

fun main(args: Array<String>){
 val user = User()
 user.share()
 user.getInfo()
}

generics

class MyData<T> {
  fun getThree(x: T){
    println(x)
    println(x)
    println(x)
  }
}

fun main(args: Array<String>){
  val i = MyData<Int>()
  i.getThree(32)

  val s = MyData<String>()
  s.getThree("hello")
}

データクラス

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

fun main(args: Array<String>){
  val p1 = Point(3, 5)
  val p2 = Point(3, 5)
  val p3 = p1.copy()

  println(p1)
  println(if (p1 == p2) "same" else "not same")
}

List

fun main(args: Array<String>){
  val sales: List<Int> = listOf(20, 30, 40)
  println(sales[1])
  println(sales.size)
  for (sale in sales){
    println(sale)
  }
}

set

fun main(args: Array<String>){
  val answers: Set<Int> = setOf(3, 5, 8, 3)
  println(answers)
  println(answers.contains(3))

  val set1 = setOf(1, 3, 5, 8)
  val set2 = setOf(3, 5, 8, 9)

  println(set1.intersect(set2))
  println(set1.union(set2))
  println(set1.subtract(set2))
}

Map

fun main(args: Array<String>){
  val users: Map<String, Int> = mapOf("kobayashi" to 10, "kagawa" to 22, "tanaka" to 33)
  println(users["kobayashi"])
  println(users.size)
  println(users.keys)
  println(users.values)
  println(users.entries)
}

map, filter, foreach

fun main(args: Array<String>){
  val prices = listOf(53.2, 48.2, 32.8)
  prices 
   /*.map { n -> n + 1.08} //*/
   .map { it * 1.08 }
   .filter { it > 50 }
   .forEach { println(it) }
}

例外処理

fun div(a: Int, b: Int){
  try {
    println(a / b)
  } catch(e: ArithmeticException) {
   println(e.message)
  }
}

fun main(args: Array<String>){
  div(3, 0)
}

Nullable型

fun main(args: Array<String>){
  val s: String? = null
  /*println(s)*/

  /*if (s != null){
    println(s.length)
  } else {
    println(null)
  }*/
  println(s?.length ?: -1)
}

Kotlin 構文1

変数

fun main(args: Array<String>){
  val msg: String = "Hello World"
  println(msg)
}

データ型

  val msg: String = "Hello World"
  val c: Char = 'a'
  val i: Int = 100
  val l: Long = 555555555555L
  val d: Double = 234.352
  val f: Float = 123.345
  val flag: Boolean = true

データ演算

val x = 10
  println(x / 3)
  println(x / 3.0)
  println(x % 3)
  var y = 5
  y++
  y--
  println(y)
  var z = 4
  z += 12
  println(z)
  val flag = true
  println(!flag)

文字列

  println("hello " + "world")

  val name = "yoshimoto"
  println("my name is $name")
  println("my score is ${12 + 43}")

  println("hello\n worl\td")

ifの条件分岐

val score = 85
  if (score > 80){
    println("Great!")
  } elseif (score > 60){
      println("good!")
  } else {
    println("soso ..")
  }

when 条件分岐

val num = 3
  when (num){
    0 -> println("zero")
    1 -> println("one")
    in 4.. 10 -> println("many")
    else -> println("other")
  }

while, for

var i = 0
  while (i < 10){
    println("loop: $i")
    i++
  }
for (i in 0..9){
    println(i)
  }

関数

fun sayHi(name: String = "tebes", age: Int = 23){
  println("hi! $name ($age)")
}

fun main(args: Array<String>){
  sayHi("tom", 22)
  sayHi()
}

関数の返り値

fun sayHi(): String {
  return "hi!"
}

fun main(args: Array<String>){
  val msg = sayHi()
  println(msg)
}

class

class User {
  var name = "me!"
  fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val user = User() // インスタンス
  println(user.name)
  user.sayHi()
}

コンストラクタ引数

class User(var name: String) { //コンストラクタ引数
  /*var name = name*/
  var team = "red"
  init {
    println("instance created: name: $name, team: $team")
  }
  fun sayHi(){
    println("hi $name")
  }
}

fun main(args: Array<String>){
  val tom = User("tom")
  println(tom.name)
  tom.sayHi()
}

Kotlin install

JetBrain社が作った、Javaを簡潔に書けるようにした言語です。JVM、Androidで動くことから、Android開発で人気を博しています。

Kotlin

エディタにKotlinのSyntaxを入れます。
kotol

インストールは公式サイトのGettingStarted->Working with the CommandlineよりSDKMAN!をインストールします。

[vagrant@localhost ~]$ curl -s https://get.sdkman.io | bash
[vagrant@localhost ~]$ source "/home/vagrant/.sdkman/bin/sdkman-init.sh"
[vagrant@localhost ~]$ cd kotlin
[vagrant@localhost kotlin]$ sdk version
==== BROADCAST =================================================================
* 15/11/16: Kotlin 1.0.5-2 released on SDKMAN! #kotlin
* 14/11/16: Gradle 3.2 released on SDKMAN! #gradle
* 10/11/16: Grails 3.2.3 released on SDKMAN! #grailsfw
================================================================================
SDKMAN 5.1.7+91
[vagrant@localhost kotlin]$ sdk install kotlin

インストールが終了したら、動作確認しましょう。

[vagrant@localhost kotlin]$ kotlin -version
Kotlin version 1.0.5-2 (JRE 1.8.0_111-b15)
[vagrant@localhost kotlin]$ kotlinc
Welcome to Kotlin version 1.0.5-2 (JRE 1.8.0_111-b15)
Type :help for help, :quit for quit
>>> 1 + 2
3
fun main(args: Array<String>){
  println("Hello World")
}
[vagrant@localhost kotlin]$ kotlinc myapp.kt -include-runtime -d myapp.jar
[vagrant@localhost kotlin]$ ls
myapp.jar  myapp.kt
[vagrant@localhost kotlin]$ java -jar myapp.jar
Hello World

scala 構文4

パターンマッチ

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

object MyApp {

  def main(args: Array[String]): Unit = {

   var points = List(
    Point(5, 3),
    Point(0, 0),
    Point(3, 4)
   )
   points.foreach(_ match{
    case Point(0, 0) => println("original")
    case Point(5, _) => println("right edge")
    case Point(x, y) => println(s"$x:$y")
   })

  }

}

option型のエラー処理

object MyApp {

  def main(args: Array[String]): Unit = {
  val scores = Map("yoshimoto" -> 55, "kimoto" -> 65)
  scores.get("tanaka") match {
   case Some(v) => println(v)
   case None => println("key not found")
  }
  }

}

Eitherによるエラー処理

object MyApp {

 // Error Either - right, left

  def div(a: Int, b: Int): Either[String, Int] = {
  if (b == 0) Left("Zero div error!")
  else Right(a / b)
  }
  def main(args: Array[String]): Unit = {

   div(10, 2) match {
   case Right(n) => println(n)
   case Left(s) => println(s)
   }

  }

}

scala 構文3

関数オブジェクト

object MyApp{

  def multi(a: Int, b: Int) = a * b
  val multFunc = (_: Int) * (_: Int)

  def main(args: Array[String]): Unit = {
    println(multFunc(3, 5))
  }

}

関数のカリー化

object MyApp {

  def main(args: Array[String]): Unit = {
    // 関数のカリー化
    val multFunc = (a: Int, b: Int) => a * b
    val multFuncCurried = (a: Int) => ((b: Int) => a * b)

    // println(multFunc(3, 5))
    // println(multFuncCurried(3)(5))

    val double = multFuncCurried(2)
    val tripple = multFuncCurried(3)

    println(double(5)) // 10
    println(tripple(5)) // 15
  }

}

関数の部分適用

object MyApp {

  def msg(from: String, to: String, text: String) = s"($from -> $to): $text"

  def main(args: Array[String]): Unit = {

  val msgToKouda = msg(_: String, "Kouda", _:String)
  println(msgToKouda("yamagata", "OK!"))
  println(msgToKouda("yoshimoto", "Great"))
  println(msgToKouda("eto", "good"))

  }

}

タプル

object MyApp {

  def swap(a: Int, b: Int) = (b, a)

  def main(args: Array[String]): Unit = {
  // val data = (12, "igarashi", 52.6)
  // println(data._1)
  // println(data._2)
  // println(data._3)
  val (x, y) = swap(32, 55)
  print(x)
  print(y)
  }

}

List

object MyApp {

  def main(args: Array[String]): Unit = {
    // val scores = List(200, 300, 400)
    val scores = 200 :: 300 :: 400 :: Nil
   println(scores.length)
   println(scores.isEmpty)
   println(scores.tail)
   println(scores.head)
   println(scores(1))
  }

}

set

object MyApp {

  def main(args: Array[String]): Unit = {
    //val answers = Set(5, 3, 4, 5)
    //println(answers)
    // println(answers.container(3))
    //println(answers(3))

    val set1 = Set(1, 3, 5, 8)
    val set2 = Set(3, 5, 7, 9)

    println(set1 & set2)
    println(set1 | set2)
    println(set1 &~ set2)

  }

}

map

object MyApp {

  def main(args: Array[String]): Unit = {

   val sales = Map("yoshida" -> 200, "kimura" -> 500)
   println(sales("yoshida"))
   println(sales("kimura"))
   println(sales.contains("murata"))

  }

}

mutable

    val scores = scala.collection.mutable.Map("ito" -> 55, "yamamoto" -> 65)
   scores("ito") = 60

map, filter, foreach

object MyApp {

  def main(args: Array[String]): Unit = {
    val prices = List(52.3, 48.6, 32.8)

    prices.map(_ * 1.08).filter(_ > 50).foreach(println)

  }

}

scala 構文2

object MyApp{

  def main(args: Array[String]): Unit = {
  // for(ジェネレータ ※変数<-データ集合)
  for (i <- 0 to 3; j <- 0 to 3 if i != j) println(s"i, $j")

  }

}

method

object MyApp{

  // method

  def sayHi: String = {
      // println("hi!")
      "hi!"
  }

  def main(args: Array[String]): Unit = {
    println(sayHi)

  }

}

メソッドの引数

object MyApp{

  def sayHi(name: String = "yokota", age: Int = 23): Unit = {
      println(s"hi! $name ($age)")
  }

  def main(args: Array[String]): Unit = {
    sayHi("bob", 35)
    sayHi("tom", 43)
    sayHi()
    sayHi(age = 18, name="jack")

  }

}

class

class User {
  val name = "my name"
  def sayHi() =  println("hi!")
}

object MyApp{
  def main(args: Array[String]): Unit = {
    val user = new User
    println(user.name)
    user.sayHi()
  }

}

コンストラクタ引数

class User(_name: String) {
  val name = _name
  def sayHi() =  println("hi!" + this.name)
}

object MyApp{
  def main(args: Array[String]): Unit = {
    val tom = new User("tom")
    println(tom.name)
    tom.sayHi()
  }

}

継承、override

class User(val name: String) {
  def sayHi() =  println("hi!" + this.name)
}

class AdminUser(name: String, val age: Int) extends User(name) {
  def sayHello() =  println("hello!" + name + "(" + age  + ")")
  override def sayHi() = println("[admin] hi " + name)
}

object MyApp{
  def main(args: Array[String]): Unit = {
    val bob = new AdminUser("bob", 23)
    println(bob.name)
    println(bob.age)
    bob.sayHi()
    bob.sayHello()
  }

}

package

package com.hpscript.model 

class User(val name: String) {
  def sayHi() =  println("hi!" + this.name)
}

class AdminUser(name: String, val age: Int) extends User(name) {
  def sayHello() =  println("hello!" + name + "(" + age  + ")")
  override def sayHi() = println("[admin] hi " + name)
}

アクセス修飾子

class User {
  protected var name = "user"
  def sayHi() =  println("hi!" + this.name)
}

class AdminUser extends User {
  override def sayHi() = println("[admin] hi " + name)
}

object MyApp{
  def main(args: Array[String]): Unit = {
    val user = new User
    val adminUser = new AdminUser
     // println(user.name)
    user.sayHi()
    adminUser.sayHi()
  }

}

object

object User {
 def getInfo() = println("User Object")
}

class User(val name: String) {
  def sayHi() =  println("hi!" + this.name)
}

object MyApp{
  def main(args: Array[String]): Unit = {
    User.getInfo()
  }

}

抽象クラス

abstract class User{
  def sayHi()
}

class Japanese extends User {
 def sayHi() = println("こんにちは")
}

class American extends User {
 def sayHi() = println("hello")
}

object MyApp{
  def main(args: Array[String]): Unit = {
   val aki = new Japanese
   val tom = new American
   aki.sayHi()
   tom.sayHi()
  }

}

trait

trait Printable {
 def print() = println("now printing ...")
}

trait Sharable {
 def share() = println("now sharing ...")
}

class User extends Printable with Sharable

object MyApp{
  def main(args: Array[String]): Unit = {
    val user  = new User
    user.print()
    user.share()
  }

}

型パラメータ

//class MyInt {
//  def getThree(i: Int): Unit = println(s"$i $i $i")
//}

class MyData[T]{
  def getThree(i: T): Unit = println(s"$i $i $i")
}

object MyApp{
  def main(args: Array[String]): Unit = {
    val i = new MyData[Int]
    i.getThree(5)
    val s = new MyData[String]
    s.getThree("hello")
  }

}

scala構文

変数

object MyApp{

  def main(args: Array[String]): Unit = {
   // 変数
   // - val:値の再代入ができない
   // - var:値の再代入ができる

   // val msg: String = "hello world";
   val msg = "hello world again"
    println(msg)
  }
}

データ型

// 整数 Byte Short Int Long
   val i = 5
   val l = 5555555555L
   val d = 32534.4
   val f = 234.34F
   val c = 'a' // 文字char
   val s = "Hello" // 文字列string
   var flag = true // Boolean
   val msg = "hello\n world again\t"
    println(msg)

四則演算

   // + - * / %
   val x = 10
   println(x / 3)
   println(x / 3.0)
   println(x % 3)

   var y = 6
   y += 10
   println(y)

   var s = "hello"
   println(s + "world")

   var flag = true
   println(!flag)

文字列

object MyApp{

  def main(args: Array[String]): Unit = {
   var name = "igarashi"
   var score = 55
   val height = 159.32

   println(s"name: $name, score: $score, height: $height")
   println(s"name: $name, score: ${score + 10}, height: $height")

   println(f"name: $name%s, score: $score%d, height: $height%f")
   println(s"name: $name%10s, score: $score%10d, height: $height%10f")
  }
}

条件分岐

object MyApp{

  def main(args: Array[String]): Unit = {
   val score = 85
   if (score > 80) println("Great!")
   else if (score > 60) println("Great!")
   else println("soso...")
  }
}

条件分岐 match

object MyApp{

  def main(args: Array[String]): Unit = {
   val signal = "red"
   var result = signal match {
    case "red" => "stop"
    case "blue" | "green" => "go"
    case "yellow" => "caution"
    case _ => "wrong signal"
   }
   println(result)
  }
}

while

object MyApp{

  def main(args: Array[String]): Unit = {
   var i = 0
   while (i < 10){
   println(i)
   i += 1
   }
  }
}

sbt 及び scalaのインストール

sbtのインストール

http://www.scala-sbt.org/0.13/docs/Installing-sbt-on-Linux.html

curl https://bintray.com/sbt/rpm/rpm | sudo tee /etc/yum.repos.d/bintray-sbt-rpm.repo
sudo yum install sbt

atomにもscala-formatのpackageをインストールしておきます。

sbt -> console でscalaのコマンドを試すことができます。

[vagrant@localhost scala]$ sbt
[info] Set current project to scala (in build file:/home/vagrant/scala/)
scala> 1 + 2
res0: Int = 3

scala> 2 + 2
res1: Int = 4

メモリが足りないと表示された場合は、sbt -mem 512でスタートさせます。

sbt -mem 512

ファイルは、src/main/scala/が推奨されています。
コンパイル実行は、sbt-> runとします。

object MyApp{

  def main(args: Array[String]): Unit = {
    println("hello world")
  }
}
[vagrant@localhost scala]$ sbt
[info] Set current project to scala (in build file:/home/vagrant/scala/)
> run
[info] Compiling 1 Scala source to /home/vagrant/scala/target/scala-2.11/classes...
[info] Running MyApp
hello world
[success] Total time: 20 s, completed 2016/11/21 16:55:04