gcontractsの基礎

62
GContracts 基礎 Groovy基礎勉強会 2013/03/09 13311日月曜日

Upload: takahiro-sugiura

Post on 28-May-2015

1.567 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: GContractsの基礎

GContractsの基礎

Groovy基礎勉強会2013/03/09

13年3月11日月曜日

Page 2: GContractsの基礎

いいわけ13年3月11日月曜日

Page 3: GContractsの基礎

只今、仕事が絶賛デスマーチ中なので、内容はグダグダです。

13年3月11日月曜日

Page 4: GContractsの基礎

13年3月11日月曜日

Page 5: GContractsの基礎

詳細は「gdgd妖精s」でググって。

13年3月11日月曜日

Page 6: GContractsの基礎

お前誰よ•名前:杉浦孝博•twitter:@touchez_du_bois•自称アニメエヴァンジェリスト•最近はVB6とVB.NETがお友達

13年3月11日月曜日

Page 7: GContractsの基礎

閑話休題13年3月11日月曜日

Page 8: GContractsの基礎

今回の内容•契約による設計•GContractsとは•GContractsの実際

13年3月11日月曜日

Page 9: GContractsの基礎

1.契約による設計Design by Contracts

13年3月11日月曜日

Page 10: GContractsの基礎

契約による設計•プログラムコードの中にプログラムが満たすべき仕様についての記述を盛り込む事で設計の安全性を高める技法(Wikipediaより)。

13年3月11日月曜日

Page 11: GContractsの基礎

契約による設計•Bertrand Meyer氏の提唱•詳細はこんな本で

13年3月11日月曜日

Page 12: GContractsの基礎

契約による設計•コードの利用者と実装者の間の契約

•利用者側が守るべきこと•実装者が約束すること

13年3月11日月曜日

Page 13: GContractsの基礎

契約による設計•主ロジックとは別に、コードとして契約内容を定義

•コード利用の責任範囲を明確化

13年3月11日月曜日

Page 14: GContractsの基礎

契約による設計•契約の条件•事前条件(Precondtion)•事後条件(Postcondition)•不変条件(Invariant)

13年3月11日月曜日

Page 15: GContractsの基礎

契約による設計•事前条件•サブルーチンの開始時に満たされるべき条件

•呼び出し側が守ること13年3月11日月曜日

Page 16: GContractsの基礎

契約による設計•事後条件•サブルーチンの終了時に保証されるべき条件

•実装側が守ること13年3月11日月曜日

Page 17: GContractsの基礎

契約による設計•不変条件•公開している操作の実行後に常に保証されるべき条件

•実装側が守ること13年3月11日月曜日

Page 18: GContractsの基礎

詳しくは•原本で

13年3月11日月曜日

Page 20: GContractsの基礎

2.GContractsとはWhat’s GContracts

13年3月11日月曜日

Page 21: GContractsの基礎

言語標準な言語•Eiffel•Bertrand Meyer氏考案•D言語

13年3月11日月曜日

Page 22: GContractsの基礎

Java•標準•assert文•ライブラリ•Contract4J, cofoja

13年3月11日月曜日

Page 23: GContractsの基礎

Groovy•標準•assert文(PowerAssert)•ライブラリ•GContracts

13年3月11日月曜日

Page 24: GContractsの基礎

GContracts•Andre Steingress氏による契約プログラミング用のライブラリ

•https://github.com/andresteingress/

13年3月11日月曜日

Page 25: GContractsの基礎

GContracts•アノテーションにより満たすべき条件をコード中に記述

•条件のコード内容はGroovyDocに出力可能

13年3月11日月曜日

Page 26: GContractsの基礎

GContracts•事前条件 -> @Requires•メソッドに指定•事後条件 -> @Ensures•メソッドに指定•不変条件 -> @Invariants•クラスに指定

13年3月11日月曜日

Page 27: GContractsの基礎

GContracts•各条件をクロージャで記述•契約に違反した場合、PowerAssertでエラー出力

13年3月11日月曜日

Page 28: GContractsの基礎

GContracts•@Ensuresのクロージャ内では、次の値を参照できる

•old : メソッド実行前の状態。Map

•result : 実行結果13年3月11日月曜日

Page 29: GContractsの基礎

GContracts•各条件を継承•各条件をクラスだけでなくインタフェースにも指定可

13年3月11日月曜日

Page 30: GContractsの基礎

GContractsimport org.gcontracts.annotations.*

@Invariant({ speed() >= 0 })class Rocket { int speed = 0 @Requires({ isStarted() }) @Ensures({ old.speed < speed }) void accelerate() { ++speed }

boolean isStarted() { true } int speed() { speed }}

13年3月11日月曜日

Page 31: GContractsの基礎

3.GContractsの実際Actuals of GContracts

13年3月11日月曜日

Page 32: GContractsの基礎

やってること•3行で言うと...

13年3月11日月曜日

Page 33: GContractsの基礎

やってること•3行で言うと...•AST変換で

13年3月11日月曜日

Page 34: GContractsの基礎

やってること•3行で言うと...•AST変換で•条件用のコードを

13年3月11日月曜日

Page 35: GContractsの基礎

やってること•3行で言うと...•AST変換で、•条件用のコードを、•コンストラクタとメソッドに埋め込み

13年3月11日月曜日

Page 36: GContractsの基礎

やってること•3行で言うと...•AST変換で、•条件用のコードを生成、•コンストラクタとメソッドに埋め込み、•実行する。

13年3月11日月曜日

Page 37: GContractsの基礎

AST変換•Abstract Syntax Tree変換•抽象構文木をこねくりまわす

13年3月11日月曜日

Page 38: GContractsの基礎

AST変換•サービスプロバイダ機能を使って、次のASTTransformationの実装クラスを指定。

•org.gcontracts.ast.ClosureExpressionEvaluationASTTransformation

•org.gcontracts.ast.GContractsASTTransformation

13年3月11日月曜日

Page 39: GContractsの基礎

ClosureExpressionEvaluationASTTransformation

•Semantic Analysisフェーズで実行

•条件のクロージャ用のクラスコードを生成

13年3月11日月曜日

Page 40: GContractsの基礎

import org.gcontracts.annotations.*

@org.gcontracts.annotations.Invariant(value = Rocket$_gc_closure1)@org.gcontracts.annotations.Contractedpublic class Rocket extends java.lang.Object {

private int speed final static boolean $GCONTRACTS_ENABLED

@org.gcontracts.annotations.Requires(value = Rocket$_gc_closure2) @org.gcontracts.annotations.Ensures(value = Rocket$_gc_closure3) public void accelerate() { ++( speed ) }

public boolean isStarted() { true }

public int speed() { speed }}

13年3月11日月曜日

Page 41: GContractsの基礎

final public class Rocket$_gc_closure1 extends groovy.lang.Closure<V extends java.lang.Object> { // (省略) public java.lang.Boolean doCall() { java.lang.Boolean $_gc_closure_result = false try { assert this.speed() >= 0 : null $_gc_closure_result = true } catch (org.codehaus.groovy.runtime.powerassert.PowerAssertionError error) { org.gcontracts.ClassInvariantViolation newError = new org.gcontracts.ClassInvariantViolation('<org.gcontracts.annotations.Invariant> Rocket \n\n' + error.getMessage()) newError.setStackTrace(error.getStackTrace()) } finally { } return $_gc_closure_result } // (省略)}

13年3月11日月曜日

Page 42: GContractsの基礎

final public class Rocket$_gc_closure2 extends groovy.lang.Closure<V extends java.lang.Object> { // (省略)

public java.lang.Boolean doCall() { java.lang.Boolean $_gc_closure_result = false try { assert this.isStarted() : null $_gc_closure_result = true } catch (org.codehaus.groovy.runtime.powerassert.PowerAssertionError error) { org.gcontracts.PreconditionViolation newError = new org.gcontracts.PreconditionViolation('<org.gcontracts.annotations.Requires> Rocket.void accelerate() \n\n' + error.getMessage()) newError.setStackTrace(error.getStackTrace()) } finally { } return $_gc_closure_result }

// (省略)}

13年3月11日月曜日

Page 43: GContractsの基礎

final public class Rocket$_gc_closure3 extends groovy.lang.Closure<V extends java.lang.Object> { // (省略)

public java.lang.Boolean doCall(java.util.Map old) { java.lang.Boolean $_gc_closure_result = false try { assert old .speed < speed : null $_gc_closure_result = true } catch (org.codehaus.groovy.runtime.powerassert.PowerAssertionError error) { org.gcontracts.PostconditionViolation newError = new org.gcontracts.PostconditionViolation('<org.gcontracts.annotations.Ensures> Rocket.void accelerate() \n\n' + error.getMessage()) newError.setStackTrace(error.getStackTrace()) } finally { } return $_gc_closure_result }

// (省略)}

13年3月11日月曜日

Page 44: GContractsの基礎

GContractsASTTransformation

•Instruction Selectionフェーズで実行

•条件の実行コード生成し、コンストラクタやメソッドに追加する

13年3月11日月曜日

Page 45: GContractsの基礎

@org.gcontracts.annotations.Invariant(value = Rocket$_gc_closure1)@org.gcontracts.annotations.Contractedpublic class Rocket extends java.lang.Object {

private int speed final static boolean $GCONTRACTS_ENABLED

public Rocket() { this.invariant_Rocket() }

13年3月11日月曜日

Page 46: GContractsの基礎

@org.gcontracts.annotations.Requires(value = Rocket$_gc_closure2) @org.gcontracts.annotations.Ensures(value = Rocket$_gc_closure3) public void accelerate() { // 準備:実行前の状態を保持 java.util.Map old = null if ( $GCONTRACTS_ENABLED ) { old = this.$_gc_computeOldVariables() } else { }

13年3月11日月曜日

Page 47: GContractsの基礎

if ( $GCONTRACTS_ENABLED ) { try { if (org.gcontracts.generation.ContractExecutionTracker.track('Rocket', 'void accelerate()', 'precondition', false)) { java.lang.Boolean $_gc_result = false org.gcontracts.ViolationTracker.init() $_gc_result = new Rocket$_gc_closure2(this, this).doCall() if (!( $_gc_result ) && org.gcontracts.ViolationTracker.violationsOccured()) { try { org.gcontracts.ViolationTracker.rethrowFirst() } finally { org.gcontracts.ViolationTracker.deinit() } } } } finally { org.gcontracts.generation.ContractExecutionTracker.clear('Rocket', 'void accelerate()', 'precondition', false) } } ++( speed )

13年3月11日月曜日

Page 48: GContractsの基礎

// 事後条件 if ( $GCONTRACTS_ENABLED ) { if (!( old .speed < speed )) { try { assert old .speed < speed : null } catch (org.codehaus.groovy.runtime.powerassert.PowerAssertionError error) { org.gcontracts.PostconditionViolation newError = new org.gcontracts.PostconditionViolation('<org.gcontracts.annotations.Ensures> Rocket.void accelerate() \n\n' + error.getMessage()) newError.setStackTrace(error.getStackTrace()) throw newError } finally { } } } // 不変条件 this.invariant_Rocket() }

13年3月11日月曜日

Page 49: GContractsの基礎

public boolean isStarted() { java.lang.Object $_gc_result = true this.invariant_Rocket() return $_gc_result }

public int speed() { java.lang.Object $_gc_result = speed this.invariant_Rocket() return $_gc_result }

13年3月11日月曜日

Page 50: GContractsの基礎

protected java.util.Map $_gc_computeOldVariables() { java.lang.Integer $old$speed = speed java.util.Map old = ['speed': $old$speed ] return old }

13年3月11日月曜日

Page 51: GContractsの基礎

protected void invariant_Rocket() { if ( $GCONTRACTS_ENABLED ) { try { if (org.gcontracts.generation.ContractExecutionTracker.track('Rocket', 'void invariant_Rocket()', 'invariant', false)) { java.lang.Boolean $_gc_result = false org.gcontracts.ViolationTracker.init() $_gc_result = new Rocket$_gc_closure1(this, this).doCall() if (!( $_gc_result ) && org.gcontracts.ViolationTracker.violationsOccured()) { try { org.gcontracts.ViolationTracker.rethrowFirst() } finally { org.gcontracts.ViolationTracker.deinit() } } } } finally { org.gcontracts.generation.ContractExecutionTracker.clear('Rocket',

13年3月11日月曜日

Page 52: GContractsの基礎

$GCONTRACTS_ENABLED

•メソッドの呼び出しごとに条件が評価されるのは遅い•$GCONTRACTS_ENABLEDで実行を制御する•-ea,-daVMパラメータで指定

13年3月11日月曜日

Page 53: GContractsの基礎

3 09, 2013 4:56:21 午後 org.codehaus.groovy.runtime.StackTraceUtils sanitizeWARNING: Sanitizing stacktrace:Assertion failed:

assert 1 == 2 | false

! at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:399)! at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.assertFailed(ScriptBytecodeAdapter.java:655)! at A.process(ConsoleScript30:22)

13年3月11日月曜日

Page 54: GContractsの基礎

Exception thrown3 09, 2013 4:50:36 午後 org.codehaus.groovy.runtime.StackTraceUtils sanitizeWARNING: Sanitizing stacktrace:org.gcontracts.PostconditionViolation: <org.gcontracts.annotations.Ensures> Rocket.void accelerate()

old.speed < speed| | | || 10 | 9| false[speed:10]! at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:399)! at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.assertFailed(ScriptBytecodeAdapter.java:655)! at Rocket.accelerate(ConsoleScript29:8)

13年3月11日月曜日

Page 55: GContractsの基礎

4.まとめAdd-up

13年3月11日月曜日

Page 56: GContractsの基礎

まとめ•原本を読んでね。•使ってみてね。

13年3月11日月曜日

Page 57: GContractsの基礎

エヴァンジェリスト活動

13年3月11日月曜日

Page 58: GContractsの基礎

私大好き

13年3月11日月曜日

Page 59: GContractsの基礎

13年3月11日月曜日

Page 60: GContractsの基礎

@bleisさん大好き

13年3月11日月曜日

Page 61: GContractsの基礎

13年3月11日月曜日

Page 62: GContractsの基礎

ご清聴ありがとうございました。

13年3月11日月曜日