'language'에 해당되는 글 18건

  1. 2017.06.30 SCALA TYPE ERASURE & TYPETAG
  2. 2017.06.28 SCALA UPPER/LOWER TYPE BOUND & VIEW BOUND
  3. 2017.05.01 Superseded by Akka HTTP
  4. 2015.05.18 FP 비엄격성 (1)
  5. 2014.11.05 scala package object
  6. 2014.10.21 scala의 lazy 비용
  7. 2014.10.20 spray는 멋지군..
  8. 2014.10.07 Enum Type을 Slick 에서 사용하기
  9. 2014.10.05 Slick
  10. 2013.10.25 Groovy

SCALA TYPE ERASURE & TYPETAG

language/scala 2017.06.30 09:28 posted by dev.bistro

다른  JVM 언어처럼 Scala  역시  컴파일시점에 type 정보를 잃어버린다.

SCALA는 JVM의 type erasure issue 를  TypeTag(이전에는 Manifest)로 해결 할 수 있다

// TODO undeprecated until Scala reflection becomes non-experimental
// @deprecated("Use `scala.reflect.ClassTag` (to capture erasures) or scala.reflect.runtime.universe.TypeTag (to capture types) or both instead", "2.10.0")
type Manifest[T]      = scala.reflect.Manifest[T]
scala> def evenElems[T : ClassTag](xs: Vector[T]): Array[T] = {
| val arr = new Array[T]((xs.length + 1) / 2)
| for (i <- 0 until xs.length by 2)
| arr(i / 2) = xs(i)
| arr
| }
evenElems: [T](xs: Vector[T])(implicit evidence$1: scala.reflect.ClassTag[T])Array[T]

scala>

 

 

 

ClassTag는 최상위의 Class의 Type정보만을 생성해준다.
ex) ClassTag[List[String]] -> collection.immutable.List

실제로 Intellij에서 Debugging 화면에서 보면 implicit evidence 를 볼 수 있다

스크린샷 2016-06-19 오후 4.07.52

스크린샷 2016-06-19 오후 3.37.56



신고

'language > scala' 카테고리의 다른 글

SCALA TYPE ERASURE & TYPETAG  (0) 2017.06.30
SCALA UPPER/LOWER TYPE BOUND & VIEW BOUND  (0) 2017.06.28
Superseded by Akka HTTP  (0) 2017.05.01
FP 비엄격성  (1) 2015.05.18
scala package object  (0) 2014.11.05
scala의 lazy 비용  (0) 2014.10.21

SCALA UPPER/LOWER TYPE BOUND & VIEW BOUND

language/scala 2017.06.28 13:58 posted by dev.bistro

하나 이상의 타입인자가 있는 클래스는 ‘제네릭 클래스’이고  타입인자를 실제 타입으로 대체하면 일반 클래스이다.

1
2
3
4
class Pair[T,S](val first:T, val second:S) //제네릭 클래스
 
val p1 = new Pair(42, "String") //추론에 의해서 일반 클래스
val p2 = new Pair[Int, String](42, "String") //명시적 선언에 의해서 일반 클래스

 

함수,  메소드도 타입인자를 가질 수 있다.

1
2
3
4
5
def getMiddle[T](a: Array[T]) = a(a.length) / 2
 
ex)
getMiddle(Array("Mary", "had")) //추론의 의해서 getMiddle 호출
val f = getMiddle[String] _ //타입인자를 명시적으로 지정함

 

타입에 제한(bound)를 걸어야 할 필요가 있다. 다음의 예로 쉽게 이해 가능하다

1
2
3
4
5
6
7
8
9
10
11
class Pair[T](val first:T, val second:S) {
def smaller = if (first.compareTo(second) < 0 ) <<--여기
}
/* first가 compareTo를 가지고 있는지 확인 할 수 없기 때문에 오류가 발생한다.
이를 해결하기 위해서는 first가 'compareTo'를 항상 가지고 있으면 될 것이다. 아래처럼 */
 
class Pair[T <: Comparable[T]](val first: T, val second: T) {
def smaller = if (first.compareTo(second) < 0 )
}
/* 처럼 'T가 반드시 Comparable[T]의 sub-type'임을 지정하면 된다.
=> 그리고 'T의 상위 타입을 지정했거나, upper bound 지정,제약했다' 라고 표현 가능 */

 

그와 비슷하게 lower bound를 선언할 수도 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Queue[+T] (private val leading: List[T], val trail: List[T] ) {
def enqueue[U >: T] (x: U) = new Queue[U](leading, x :: trail)
}
// U >: T 를 이용해 T 를 U 의 하위 바운드로 지정했으니 U가 T의 슈퍼클래스여야 한다.
 
ex1)
/* Fruit 클래스에 2개의 서브 클래스 Apple, Orange가 있다.
Queue[Apple]에 Oragne를 추가할 수 있고 결과는 Queue[Fruit]가 된다. */
 
ex2)
class Animal
class Bird extends Animal
class Chicken extends Bird
 
val flock = List(new Bird, new Bird)
flock: List[Bird] = List(Bird@7e1ec70e, Bird@169ea8d2)
 
new Chicken :: flock
res53: List[Bird] = List(Chicken@56fbda05, Bird@7e1ec70e, Bird@169ea8d2)
 
// 처럼 공통적인 각기 다른 타입을 하나로 분류할 수 있는 이점이 생긴다.

 

upper , lower bound와 같은 상하위가 아니라 implicit의 암묵적 변환에도 그대로 사용하고 싶을 경우에는 <% 를 사용한다.

1
2
3
4
5
6
7
8
9
10
11
class Pair[T <: Comparable[T] ](val first:T, val second:T)
val p = new Pair(4,2)
 
output> Error:(6, 9) inferred type arguments [Int] do not conform to class Pair's type parameter bounds [T <: Comparable[T]]
// 4, 2같은 Int는 Comparable를 구현하지 않기 때문이다 하지만 RichInt에는 있다.
 
class Pair[T <% Comparable[T] ](val first:T, val second:T)
/* 처럼 수정하면 된다. 이를 다시 풀어보면
a. T가 Comparable[T]로 암묵적 변환이 가능하다 라는 의미이다.
b. T를 Comparable[T]로 다룰수 있는 모든 T type을 사용 할 수 있다.
c. class Pair[T ](..)(implicit imp: T => Comparable[T]) 의 축약형이다.


신고

'language > scala' 카테고리의 다른 글

SCALA TYPE ERASURE & TYPETAG  (0) 2017.06.30
SCALA UPPER/LOWER TYPE BOUND & VIEW BOUND  (0) 2017.06.28
Superseded by Akka HTTP  (0) 2017.05.01
FP 비엄격성  (1) 2015.05.18
scala package object  (0) 2014.11.05
scala의 lazy 비용  (0) 2014.10.21

Superseded by Akka HTTP

language/scala 2017.05.01 20:21 posted by dev.bistro

spary 팀이 akka-http 에 합류하더라도, spary는 계속 진행될 거다 라는 내용은.. 아마 https://github.com/sirthias의 글에서 본 걸로 기억이 난다. 당시만 해도 akka-http가 시작되는 정도였지만  spary는 거의 중단된채 akka쪽에 힘쓰는걸 보니, 말과는 다르게 접히겠구나 생각되었다.  

오늘 갑자기 생각나서 들어가보니  PRdocumentation 와는 다르게 Superseded by Akka HTTP 라는 내용으로 README.md가 대체되었다. 그리고 sparu 1.3.3 과 함께 고민을 하게 하면 akka-http는 experimental 에서 2.5.0 까지 나왔인줄 알았는데 현재 10.0.5 -_-;

akka에서 분리되어 독립 project가 생겼고,버전을 10으로 크게 올렸다.

akka: http://akka.io/docs

akka-http : http://doc.akka.io/docs/akka-http/current/scala.html



신고

'language > scala' 카테고리의 다른 글

SCALA TYPE ERASURE & TYPETAG  (0) 2017.06.30
SCALA UPPER/LOWER TYPE BOUND & VIEW BOUND  (0) 2017.06.28
Superseded by Akka HTTP  (0) 2017.05.01
FP 비엄격성  (1) 2015.05.18
scala package object  (0) 2014.11.05
scala의 lazy 비용  (0) 2014.10.21

FP 비엄격성

language/scala 2015.05.18 22:58 posted by dev.bistro

p83~

1. 엄격성과 비엄격성


- 엄격성  (strictness)

- 비엄검성 (non-strictness; laziness)

 : 함수의 한 속성으로, 함수가 엄격하지 않다는 것은 하나 이상의 인수들을 '평가하지 않을 수도'있다는 뜻이다.


대부분의 프로그래밍 언어에서는 엄격한 함수가 기본이다. 스칼라로 기본 정의는 엄격한 함수이다. 

하지만 그 개념 자체는 익숙하다. 부울 함수의 &&, ||의 단축 평가는 '엄격하지 않다' 첫 조건이 true이어야만 두 번째 조건을 검사한다.

스칼라의 if 역시 '비엄격성 함수'로 생각할 수 있다(단 매개변수 자체에 대해서는 엄격하다).


여튼  스칼라는  인수들 중 일부가 평가되지 않아도 호출이 성립하는 비엄격함수를 작성 할 수 있다.



2. 스칼라의 비엄격성 함수 작성

def if2[A](cond:Boolean, onTrue:() =>A, onFalse:() =>A) : A = if (cond) onTrue() else onFalse()
처럼 ()=> 즉, Function0[A] 형식으로 인수를 표기해준다.
if2(true, ()=>println("A"), ())=>println("B") )
를 실행하면 결과는 'A'
이 활용방법이 흔하기 때문에 스칼라에서는 좀 더 깔끔(축약)한 구문을 제공한다.
def if2[A](cond:Boolean, onTrue: =>A, onFalse: => A) : A = if (cond) onTrue else onFalse


3. 비엄격성 함수에서 평가 평가되지 않은 채로 함수에 전달되는 인수는 '함수의 본문에서 참조된 장소마다 한번씩 평가된다'

def mayBeTwice(b:Boolean, i: => Int) = if (b) i+i else 0 val x = mayBeTwice(true, {println("hi"); 1+41} )

결과는

hi
hi
x:Int = 84


mayBeTwice함수에서 i는 2번 참조되고, 그렇기 때문에 hi가 2번 출력된다.  만약 캐싱을 적용하고 싶다면 lazy를 이용한다.

def m(b:Boolean, i: => Int) = {
	lazy val j=i; if(b) j+j else 0
}
"스칼라의 비엄격 함수의 인수는 by value가 아닌 by name이다"


신고

'language > scala' 카테고리의 다른 글

SCALA UPPER/LOWER TYPE BOUND & VIEW BOUND  (0) 2017.06.28
Superseded by Akka HTTP  (0) 2017.05.01
FP 비엄격성  (1) 2015.05.18
scala package object  (0) 2014.11.05
scala의 lazy 비용  (0) 2014.10.21
spray는 멋지군..  (0) 2014.10.20

scala package object

language/scala 2014.11.05 17:00 posted by dev.bistro

스칼라의 package object는 어떤 모습을 하고 있을까?


package com {

  package sub {

    class klazz  {

      val name = pubValue

    }

  }

  package object sub {

    val pubValue = "A"

    private val priValue = "B"

    def pubMethod() = "C"


  }

}


1. com/sub 폴더 내에는 다음과 같은 파일들이 생성된다.

- klazz.class

- package$.class

- package.class


2. package, package$

$ javap -p package

public final class com.sub.package {

  public static java.lang.String pubMethod();

  public static java.lang.String pubValue();

}

public final class com.sub.package$ {

  public static final com.sub.package$ MODULE$;

  private final java.lang.String pubValue;

  private final java.lang.String priValue;

  public static {};

  public java.lang.String pubValue();

  private java.lang.String priValue();

  public java.lang.String pubMethod();

  private com.sub.package$();

}



- companion object 를 가지는 class 와 유사한 모습으로 생성된다.
- package object의 method와 var 맴버는 public static 으로 생성된다.

신고

'language > scala' 카테고리의 다른 글

Superseded by Akka HTTP  (0) 2017.05.01
FP 비엄격성  (1) 2015.05.18
scala package object  (0) 2014.11.05
scala의 lazy 비용  (0) 2014.10.21
spray는 멋지군..  (0) 2014.10.20
Enum Type을 Slick 에서 사용하기  (0) 2014.10.07

scala의 lazy 비용

language/scala 2014.10.21 17:25 posted by dev.bistro

lazy val x = 솰라솰라...


단순히 늦은/지연 연산일 줄만 알았다...


test

class lazyval {
    lazy val x = 5
}

를 scalac로 컴파일하고 다시 디컴파일 해서 내용을 보면

public class lazyval

{


    private int x$lzycompute()

    {

        synchronized(this)

        {

            if(!bitmap$0)

            {

                x = 5;

                bitmap$0 = true;

            }

            BoxedUnit _tmp = BoxedUnit.UNIT;

        }

        return x;

    }


    public int x()

    {

        return bitmap$0 ? x : x$lzycompute();

    }


    public lazyval()

    {

    }


    private int x;

    private volatile boolean bitmap$0;

}


- voliatile boolean의 flag가 하나 생성된다
- 초기화 되지 않았다면 synchronized 으로 묶어 초기화를 한다 (오쉿1)
- 이후 voliatile bitmap$0을 계속 참고한다.(오쉿2)

읽기 비용이 있다는걸 잊지 말자. 

자세한 내용은 SIP-20 http://docs.scala-lang.org/sips/pending/improved-lazy-val-initialization.html#version_v4__the_cas_improvement

신고

'language > scala' 카테고리의 다른 글

FP 비엄격성  (1) 2015.05.18
scala package object  (0) 2014.11.05
scala의 lazy 비용  (0) 2014.10.21
spray는 멋지군..  (0) 2014.10.20
Enum Type을 Slick 에서 사용하기  (0) 2014.10.07
Slick  (0) 2014.10.05
TAG Lazy, scala

spray는 멋지군..

language/scala 2014.10.20 17:51 posted by dev.bistro

scala 기반에 프레임웍으로는 제일 유명한게 Play Framework.... 나름 몇일몇주를 번역해가며 스터디 한 놈이지만... 선택받지는 못했다. 
 그 외에도 scalatra나, finatra도 있지만 지금 API Platform을 구성하는데는 spray 1.3.1 을 사용중... 얘도 actor 기반이고, 간결하다.


테스트와 성능이슈를 위해서 Route를 다시 한번  Route로 묶음으로서 원하는 요구사항은 몇줄만에 해결

  val mockRoute =

    pathPrefix("mock") {

      parameter('delay.as[Int] ){

        delay => {

          Thread.sleep(delay)

          logger.warn("delay {} millisecond" , delay.toString)

          apiRoute

        }

      }

    }



신고

'language > scala' 카테고리의 다른 글

scala package object  (0) 2014.11.05
scala의 lazy 비용  (0) 2014.10.21
spray는 멋지군..  (0) 2014.10.20
Enum Type을 Slick 에서 사용하기  (0) 2014.10.07
Slick  (0) 2014.10.05
Functional Programming Principles in Scala 끝!  (1) 2013.06.04
TAG play, scala, SPRAY

Enum Type을 Slick 에서 사용하기

language/scala 2014.10.07 16:08 posted by dev.bistro


1. Enum 타입의 사용

scala.Enumeration을 상속한다.

object REQUEST_METHOD_TYPE extends Enumeration {
  type REQUEST_METHOD_TYPE = Value
  val GET, POST = Value
}


2. Slick의 선언

implicit val MethodMapper  = MappedColumnType.base[REQUEST_METHOD_TYPE,String] ( s=>s.toString, s=>REQUEST_METHOD_TYPE.withName(s))

def method = column[REQUEST_METHOD_TYPE]("method", O.NotNull, O.Default(REQUEST_METHOD_TYPE.GET), O.DBType("VARCHAR(20)"))


신고

'language > scala' 카테고리의 다른 글

scala의 lazy 비용  (0) 2014.10.21
spray는 멋지군..  (0) 2014.10.20
Enum Type을 Slick 에서 사용하기  (0) 2014.10.07
Slick  (0) 2014.10.05
Functional Programming Principles in Scala 끝!  (1) 2013.06.04
Scala Tuple  (0) 2013.03.12
TAG enum, scala, Slick

Slick

language/scala 2014.10.05 01:47 posted by dev.bistro

어떤 언어를 사용하던지, 무엇을 만들던지 DB와의 연결은 중요한 포인트임이 틀림없다. 각 언어별로 대표적인 프레임웍이 있듯이 스칼라 역시 마찬가지이다. 스칼라를 위한 typesafe는 몇몇 표준 기술 셋을 정의하고 있다 ( http://typesafe.com/platform )

이 중에 오늘 얘기하고자 하는 것은 Slick ( http://typesafe.com/platform/tools/scala/slick ) 이다.
처음 접했을 때 생소한 개념이기도 했고, 정확한 사용방법을 숙지 할 수가 없었기에 현재 사용하고 있는 방법들을 공유하면서 어떤식으로 쓰면 되는지를 공유할 예정이다.

개념등이나 자세한 사용법은 래퍼런스 문서를 참고하면 될것이고, 이렇게 쓰는 거구나~ 정도만 참고 하시면 될듯하다. Play 1에 있던 Anorm이나 Squeryl보다는 좀 더 일반적으로 사용되고, 래퍼런스도 많고, 표준 스택이라 배움에 후회는 없을 것이다. 


* 주의 *
Slick은 2013년 중순경 2.0 이 발표되면서 약간의 문법이 변화되었다. 구글링을 할 때 하더라도 버전을 주의해서 보고 아래의 문서를 참고하면 좋을 것이다.

- http://slick.typesafe.com/news/all-news.html : http://typesafe.com/platform/tools/scala/slick
- MIGRATION GUIDE FROM SLICK 1.0 TO 2.0 : http://slick.typesafe.com/doc/2.0.0-RC1/migration.html


Slick은  기존의 JPA와 Hibernate, Mybatis와는 달리  " Slick is a Functional Relational Mapping (FRM) library  " 으로 소개한다. (FRM ???) FRM이라고는 하지만 전통적인 쿼리를 지원하므로 다양한 사용 방법을 알아보겠다.


* 아래 코드에 사용된 정보 *

- Scala 2.10.4
- val slickVersion = "2.1.0"
- val slick = "com.typesafe.slick" %% "slick" % slickVersion
- val slickext = "com.typesafe.slick" %% "slick-extensions" % slickVersion



Story1 - Database connection

1-1) http://slick.typesafe.com/doc/2.1.0/gettingstarted.html#database-connection 처럼 사용 할 수 있다.

1-2) Java개발자에 익숙한 DataSource를 사용 할 수도 있다.

  lazy val OSlickDataSource = com.typesafe.slick.driver.oracle.OracleDriver.simple.Database.forDataSource( OBasicDataSource)

  lazy val HSlickDataSource = scala.slick.driver.MySQLDriver.simple.Database.forDataSource( HBasicDataSource )

* HBasicDataSource와 OBasicDataSource는 DBCP의 BasicDataSource 이다.
* Oracle, MySQL 두개를 사용하고 있고, DataSource가 필요한 Java-Project도 있기 때문에 위와 같이 사용하고 있다.


Story2 - Plain Query

일반적인 Query Base방식을 지원한다. Mybatis나 JDBC에 익숙한 개발자라면 무리없이 이해할 수 있을 것이기 떄문에 이것부터 시작을 해보자.

HSlickDataSource withSession {
implicit  session=> 
Q.updateNA(s"drop table if exists $readyTableName").execute
(Q.u + "drop table a").execute

처럼 drop table명령을 실행 할 수 있다. 둘 다 같은 방식이다. insert 또한 마찬가지이다.

def insert(c: SynObject) = (Q.u + "INSERT INTO $tempTableName(SVALUE) VALUES (" + c.svalue + ")" ).execute
data.foreach(insert) //data List[SynObject]

처럼 batch insert가 가능하지만



val psmt = session.prepareInsertStatement(  s"INSERT INTO $tempTableName(SCODE, SVALUE, STATUS) VALUES (?, ?, ?)" )

for(line <- data.zipWithIndex ) {
  psmt.setString(1, line._1.scode)
  psmt.setString(2, line._1.svalue)
  psmt.setString(3, line._1.status)
  psmt.addBatch()
  if(line._2 % 1000 == 0) psmt.executeBatch
}
psmt.executeBatch

처럼 PreparedInsert BatchInsert를 이용하여 성능을 향상 시킬수 있다.



Story3 -  Lifted Embedding API

Plain Scala의 특징과 장점을 활용하려면 이 방법으로 사용하면 된다.
우선은 1개의 DB 테이블을 Scala Class로 매핑을 하자.


3-1) case class의 선언

case class ForbiddenKeyword( id:Int, collId:String, keyword:String, itemStatus:Option[String])

금칙 키워드 정보를 가지고 있는 Class를 선언한다.


3-2) Table 매핑

class ForbiddenKeywordTable(tag:Tag) extends Table[ForbiddenKeyword](tag, "FORBIDDEN_KEYWORD") {

  def id = column[Int]("id", O.PrimaryKey, O.NotNull)
  def collId = column[String]("collId", O.NotNull)
  def keyword = column[String]("keyword", O.NotNull)
  def itemStatus = column[String]("itemStatus")
  def * = (id, keyword, itemStatus) <> (ForbiddenKeyword.tupled, ForbiddenKeyword.unapply)
}

FORBIDDEN_KEYWORD 테이블 정보를 ForbiddenKeywordTable 클래스로 선언하였다.
id필드는 PK, NotNull이고 Int타입이고, itemStatus 필드는 String 타입이다. 이후에...



val forbidden = TableQuery[ForbiddenKeywordTable]


def getForbiddenKeywordList(collId:String = null) = {
ds withSession {
 implicit session => {
   collId match {
     case e:String => forbidden.filter(_.collId === collId).list
     case _ => forbidden.list
   }
 }
}
}


select * from FORBIDDEN_KEYWORD  
select * from FORBIDDEN_KEYWORD  wehre collId = ?
를 수행 할 수 있다.


3-3) Null 허용

위에서 NotNull 필드는 column 정의부에 선언했지만 allow Null은 어떻게 해야할까? Scala에서는 Option으로 처리 할 수 있다. 예를 들어 keyword column이 Null을 허용한다고 할 경우  def * (class mapping 부분)을  아래처럼 .?를 붙이면 된다.

def * = (id, keyword.?, itemStatus) <> (ForbiddenKeyword.tupled, ForbiddenKeyword.unapply)

이 부분은 ColumnExtensionMethods trait class를 참고로 하면 된다. 아래에서 다시 설명 한다.


3-4) Column Extension Method

컬럼을 매핑할 때 컬럼마다 일정 로직을 태우면서 매핑 할 수 있다.
이 부분은 ColumnExtensionMethods trait class를 참고로 하면된다. 이 부분을 조금 더 훑어보면 NumericColumnExtensionMethods, StringColumnExtensionMethods 등을 볼 수 있는데 다양한 메소드를 컬럼에 적용할 수 있음을 볼 수 있다.
예를 들어 Int-Column필드는 절대값을 가져 올수 있고 ( ex: id.abs ) String-Column은 trim을 적용 할 수도 있다. (ex : keyword.trim )
ExtensionMethods.scala


3-5) 테이블 명을 파라미터로 변경

1 테이블과 1 Class로 매핑된다면 문제가 없지만. 1 Class가 여러 테이블에 매핑 (즉, 스키마가 동일한 여러 테이블)이 존재한다면 3-2)방식을 여러개 작성하는 것은 낭비이다. parameter로 테이블 명을 받도록 변경해보자.

class ForbiddenKeywordTable(tag:Tag, tableName:String) extends Table[ForbiddenKeyword](tag, tableName) {...} 

으로 선언한 이후에 아래 처럼 선언을 해서 사용을 한다.

val adminKeyword = TableQuery[ForbiddenKeywordTable]((tag:Tag) => new  ForbiddenKeywordTable(tag, "ADMIN_FORBIDDEN_KEYWORD"))

val forbidden = TableQuery[ForbiddenKeywordTable]((tag:Tag) => new ForbiddenKeywordTable(tag, "FORBIDDEN_KEYWORD"))


3-6) trait CRUD

이런식의 매핑 정보를 나열하다 보면 어쩔수 없이 중복 코드를 많이 작성하게 된다. 특히 기본적인 CRUD에서 많이 보이는데 이 부분을 공통하 시켜보자.

개인적 요구 사항

#1. MySQL/ Oracle DB2개를 쓰고 각 테이블의 Schema는 동일하다
#2. 동일한 스키마를 여러 테이블이 사용한다.
#3. 공통 CRUD는 가능한 1번만 작성하고 싶다.

trait CRUD[T] {

  implicit val driver: JdbcProfile
  import driver.simple._
  implicit val tableName:String
  implicit val prop:TableQuery[_<: Table[T]]

  def count(implicit  session:Session) =  prop.length.run
  def findAll(implicit  session:Session) = prop.list
  def insert(obj:T)(implicit  session:Session) = prop += obj
  def insert(obj:List[T])(implicit  session:Session) = prop.insertAll(obj: _*) 

  def drop(implicit  session:Session) =  if ( MTable.getTables(tableName).list.nonEmpty)   prop.ddl.drop

  def delete(obj:T )(implicit session:Session)
}

jdbcProfile과 tableName을 인자로 사용하도록 하였고, TableQuery를 내재화 시켜서 몇몇 메소드를 공통화 하였다. 
delete는 그렇게 할 수 없어서 각자 구현하도록 남겨놓았다.


Story 4 - 사용후기

생각보다 학습비용이 많이 든다. 기존에 사용하던 습관이 남아 있어서 인지... 이건 이렇게 했는데 Slick에서는 어떻게 해야하지 ? 라는 고민을 많이 했다. 생각보다 구글링/so에서 원하는 만큼 결과를 얻지 못해 github.com에서 많은 프로젝트를 참고하기도 하였다.

다른 익숙한 프레임웍만큼 코어까지 살펴보기엔 꽤 오랜 시일이 걸릴 것 같지만, Slick을 처음 적용해 가면서 조금씩 긍적적인 생각이 든다. ... 

신고

'language > scala' 카테고리의 다른 글

spray는 멋지군..  (0) 2014.10.20
Enum Type을 Slick 에서 사용하기  (0) 2014.10.07
Slick  (0) 2014.10.05
Functional Programming Principles in Scala 끝!  (1) 2013.06.04
Scala Tuple  (0) 2013.03.12
2.10을 위한 scala-ide plugin 재설치  (0) 2013.03.12
TAG Slick

Groovy

language 2013.10.25 02:05 posted by dev.bistro


아마존의 최근 세미나에 참석했다. eb이니 cloud-front이니 듣고만 있어도 혹하는 제품들이 연이어 발표되고 있지만, 쉬운 scaleout만큼 관리는 쉽지 않은 것 같다. aws의 큰 유저중 하나인 netflix는 그러한 문제점을 몇년전부터 인지하고 asgard로 aws instance를 관리하고 있다.

최근에 개인적으로 가장 큰 관심사는 3개의  JVM 언어 Java, Scala, Groovy 그리고 3개의 G. Gradle , Grails, Gradle이다. asgard를 알게 된건 netflix이거나 aws여서가 아니다. 오직 groovy & grails 때문이다. 


http://techblog.netflix.com/2012/06/asgard-web-based-cloud-management-and.html

asgard는 github에 오픈되어 있으며 ( https://github.com/Netflix/asgard ) 매우 쉽게 실행이 가능하고 aws secure key를 넣는것만으로 바로 운영이 가능하다. 


spring의 제품중 하나인 groovy이미로 pivotal 에서도 어제 글을 하나 올려주었다.

http://blog.gopivotal.com/case-studies-2/netflix-amazon-asgard-groovy-grails-elastically-scaling-apps-for-40-million-internet-tv-viewers

이 글에서는 Why Groovy and Grails for Asgard?  이 부분이 재미있다.
익숙함이란 버릴수가 없는 최고의 장점이다. 자바 개발자로서는 Groovy의 편안함 (Scala와는 비교할수도 없이 마음에 안정감을 주더라 ㅠ) 그리고 정체된 JDK를 대신해 빠른 개발을 할 수 있는 매력때문에 Groovy를 선정했다고 
Sondow 는 말한다

좀있으면 Java8이 나올거고 그럼 문법적인 장점은 쌤쌤? 지금까진 Spring project template에 의지했지만 boot로 grails의 편리함이 쌤쌤?
그럼 남는 이점은 script 언어로서 정도의 포지션이 되려나? 몇년뒤의  둘의 관계가 궁금해진다.

신고

'language' 카테고리의 다른 글

Groovy  (0) 2013.10.25
switch, if (java 1.6.0_30  (0) 2013.01.07


티스토리 툴바