2013-02-10 1 views
0

한 가지 메소드에서 예외가 발생하고 다른 메소드에서 오류 코드가 반환 될 수있는 Java 라이브러리를 사용해야합니다. 지금까지 그것은 추한 코드로 연결 같은변경 가능한 상태를 유지하지 않고 스칼라에서 IO 리소스를 해제하십시오.

val txn = mgr.prepareTransaction() 
val accessRecord = txn.readByQuery(...) 
var state : Either[MyError, Result] = null // 
try { 
    // do something here 
    val result = txn.runCodeWithin(new Callable[Result]() {...}) 
    if (result == -1) { 
    state = Left(CanNotReadRecord) 
    } else { 
    state = Right(txn.getCachedRecord()) 
    } 
} catch { 
    case e: Exception => state = Left(GeneralError(e)) 
} finally { 
    state match { 
    case Right(_) => txn.commit(); 
    case _  => txn.rollback(); 
    } 
} 

내가 VAR 마지막 블록의 상태를 확인 할 수있는 능력으로 상태 치우는에 주로 관심. 제발 조언.

+0

모든 이상 같은 패턴이있는 경우, 3 개 인수합니다 (MGR, readByQuery에 대한 인수 및 runCodeWithin에 대한 호출을 만들 수있는 블록을) 소요 하나의 유틸리티 방법으로 추함을 고려 할 수 있습니다. 그런 다음 유틸리티 메소드를 대신 사용하십시오. 이 특별한 방법을 예쁘게 만들지는 않겠지 만, 적어도 그것의 발자국을 줄일 것입니다. – huynhjl

+0

그게 내가 실제로하고있는거야 - 암시 적 오류 생산자와 유틸리티 방법으로 트랜잭션 관리 및 커서를 추출하십시오. 그러나 그것은 아직도 이상하게 보인다. – jdevelop

답변

4

스칼라 2.10은 의 사용 사례를보다 기능적으로 대체 한 Try 클래스를 도입했습니다. 이것은 일반적인 모나드 연산 (for-comprehensions 작업을 만드는 것)과 다른 유용한 메소드를 가지고 있습니다. check out the docs for Try here

Try을 사용하고 CanNotReadRecordCanNotReadRecordException으로 대체하여 코드를 다시 구현할 수 있습니다. 해당 대체 기능을 제외하고는 기능적으로 귀하의 예와 동일해야합니다.

def txResults(txn: Transaction): Try[Record] = for { 
    result <- Try{ txn.runCodeWithin(...) } 
    checked <- result match { 
     case -1 => Failure(new CanNotReadRecordException) 
     case _ => Success(txn.getCachedRecord) 
    } 
} yield checked 

txResults(txn) match { 
    case Success(record) => txn.commit() 
    case Failure(e) => txn.rollback() //and maybe handle `e` 
} 
3

Scala ARM (자동 리소스 관리) 라이브러리는 모든 종류의 것을 우아하고 완벽하게 처리합니다.

확인해보십시오.

+1

Upvoted 나는 라이브러리를 사용하는 것이 여전히이 특별한 예제에서 그렇게 중요하지 않을 것이라고 생각한다. 왜냐하면'result'에 따라 에러 또는 레코드가 있기 때문에 [MyError, Result] 중 하나가 나오기 때문이다. 그래서'resource.either'를 사용하면'[Seq [Exception], [MyError, Result]] 중 어느 것이 든 [MyError, Result] 중 하나로 결합되어야합니다. – huynhjl