개발, 테스트와 관련된 용어이다. 



경계 조건은 영어로 edge case로서, 하나의 매개변수 값이 극단적인 최대값 또는 최소값이어서 로직에 문제가 발생할 수 있는 경우를 말한다. 

더 상세히 말하면..알고리즘에 처리하는 데 있어서 입력 매개변수의 유효 범위는 정해진다. 입력 범위가 다양해 질 수 있다. 따라서 테스트를 사용해서 입력 범위를 확인(validate)할 수 있다. 


예측이 될 수도 있고, 예측이 안될 수도 있지만, 문제를 어떻게든 해결할 수 있다.




복합 경계 조건은 영어로 corner case로서, 변수와 환경적인 요소로 인해서 로직에 문제가 발생할 있는 경우를 의미한다. 코드가 변경되지 않았는데, 테스트가 잘 성공하다가 실패할 때, 어떤 요인 때문에 발생할 수 있다.  랜선이 문제가 많거나 습도가 높은 컴퓨팅 환경 때문에 영향을 받을 수도 있다. 


재현, 테스트가 무척 어렵다.









Posted by '김용환'
,



실행 중인 메소드에서 호출 객체 인스턴스 참조를 자기 참조(self reference)라 한다. 

자바의 this와 동일하며, 스칼라에서도 this를 그대로 쓸 수 있다. 


case class Member(val name: String) {
def compare(that: Member): Boolean = {
if (this.name == that.name) true
else false
}
}


테스트 코드는 다음과 같다.

println(Member("samuel").compare(Member("samuel")))
println(Member("samuel").compare(Member("excel")))


결과는 다음과 같다.


true

false









this에 대한 추가 타입으로 self type annotation이고, this에 대한 앨리어스로 쓰는 self를 보자.

느낌은 바로 아래와 같다. 

trait Trait {
private[this] val self = this
}


이번에는 self 지시자를 테스트한다. 


trait Self {
self =>
val name = "outer"
val innerObject = new AnyRef {
val name = "inner"
println(name)
println(this.name)
println(self.name)
}
}

object Main extends App {
new AnyRef with Self
}

결과는 다음과 같다.


inner

inner

outer


트레이트에 self => 를 추가하면 멤버 필드는 트레이트가 소유한 것을 의미한다. 내부 클래스를 선언할 때, 내부 클래스의 동일한 변수를 참조할 때 self를 사용했다. 




물론, abstract class를 써도 동일한 결과는 발생한다. 



abstract class Self {
self =>
val name = "outer"
val innerObject = new AnyRef {
val name = "inner"
println(name)
println(this.name)
println(self.name)
}
}
class ChildSelf extends Self {
}

object Main extends App {
new ChildSelf
}


self를 name conflicting(이름 충돌)을 피하기 위해서 사용했다. 이 방법 외에, Injection하는 방식을 설명한다.



예는 마치 서비스 코드와 비슷하게 진행했다. 모르는 것이 훨씬 많아서 대충 코드를 썼다.


Controller - UserService (UserServiceImpl) 구조이다. 스칼라 Main 메소드에  withController with UserServiceImpl을 추가해서 믹스인(mixin)을 진행했다. 



trait UserService {
def printUser : Unit
}

trait UserServiceImpl extends UserService {
def printUser : Unit = println("samuel")
}

trait Controller {
self: UserService =>
}

object Main extends App with Controller with UserServiceImpl {
printUser
}


결과는 samuel으로 출력된다.



Controller 트레이트에서는 self:UserService 만 가르켰고 UserServiceImpl에 대한 정체는 알지 못한다.


Controller를 믹스인한 Main 객체에서 UserSerivceImpl 트레이트를 믹스인하면서, UserService를 통해 UserServiceImpl을 구했다. 


즉, Dependency Injection을 구현했다. 


스칼라에서는 이를 Cake Pattern 이라고 한다. 



재미있을 만한 링크는 다음에 있다. 


http://www.andrewrollins.com/2014/08/07/scala-cake-pattern-self-type-annotations-vs-inheritance/



https://coderwall.com/p/t_rapw/cake-pattern-in-scala-self-type-annotations-explicitly-typed-self-references-explained


http://marcus-christie.blogspot.kr/2014/03/scala-understanding-self-type.html



http://www.cakesolutions.net/teamblogs/2011/12/19/cake-pattern-in-depth




Posted by '김용환'
,

[scala] sugar 의미

scala 2016. 9. 27. 11:42


scala 문서나 책을 보면 sugar, desugar 라는 단어가 종종 나온다.


scala compiler가 jvm으로 translate할 때, 다른 언어에서 볼 수 없는 scala의 함수형 프로그래밍을 재밌게 진행할 수 있는 문맥(예, under score, case class 등)에서 많이 쓰이는 것 같다.


* scala sugar : 스칼라의 문법


* syntactic sugar : 편리한 문법, 간편 표기법


* desugar : 번역한다.




Posted by '김용환'
,