More Related Content
PDF
PPTX
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc PDF
Markup Template Engine introduced Groovy 2.3 PDF
PDF
Gws 20130315 gradle_handson PDF
Introduce Groovy 2.3 trait PDF
Groovy Shell Scripting 2015 PDF
Groovy Bootcamp 2015 by JGGUG What's hot
PDF
PDF
About GStreamer 1.0 application development for beginners PPTX
Node.js - JavaScript Thread Programming PDF
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8 PDF
C#でOpenCL with OpenTK + Cloo PDF
Reactive Extensionsで非同期処理を簡単に PPTX
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~ PDF
Project Loom - 限定継続と軽量スレッド - ODP
PDF
Java8 コーディングベストプラクティス and NetBeansのメモリログから... PDF
Indy(Invokedynamic) and Bytecode DSL and Brainf*ck PDF
PDF
PDF
PDF
New features of Groovy 2.0 and 2.1 PDF
Read Groovy Compile process(Groovy Benkyoukai 2013) PDF
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」 PDF
Groovy base gradle_20130309 PDF
GroovyServ concept, how to use and outline. PDF
Viewers also liked
PDF
PDF
PDF
PDF
Closures and methodMissing are real PDF
PDF
Groovyしたり RPしなかったり あとは時々布教活動したり PDF
Similar to GContractsの基礎
PDF
gen-class とバイトコード(第3回 gen-class 勉強会資料) PDF
Java開発の強力な相棒として今すぐ使えるGroovy PDF
Javaセキュアコーディングセミナー東京第1回 講義 PDF
PPTX
PPTX
PDF
Unit testing JavaScript with JUnit/JavaFX KEY
関ジャバ JavaOne Tokyo 2012報告会 PDF
KEY
Java One 2012 Tokyo JVM Lang. BOF(Groovy) KEY
GContractsの基礎
- 1.
GContracts
の
基礎
Groovy基礎勉強会
2013/03/09
13年3月11日月曜日
- 2.
- 3.
- 4.
- 5.
- 6.
お前誰よ
• 名前:杉浦孝博
• twitter:@touchez_du_bois
• 自称アニメエヴァンジェリスト
• 最近はVB6とVB.NETがお友達
13年3月11日月曜日
- 7.
- 8.
今回の内容
•契約による設計
• GContractsとは
• GContractsの実際
13年3月11日月曜日
- 9.
- 10.
契約による設計
• プログラムコードの中にプ
ログラムが満たすべき仕様に
ついての記述を盛り込む事で
設計の安全性を高める技法
(Wikipediaより)。
13年3月11日月曜日
- 11.
契約による設計
• Bertrand Meyer氏の提唱
• 詳細はこんな本で
13年3月11日月曜日
- 12.
契約による設計
• コードの利用者と実装者の
間の契約
• 利用者側が守るべきこと
• 実装者が約束すること
13年3月11日月曜日
- 13.
契約による設計
• 主ロジックとは別に、コー
ドとして契約内容を定義
• コード利用の責任範囲を明
確化
13年3月11日月曜日
- 14.
契約による設計
• 契約の条件
• 事前条件(Precondtion)
• 事後条件(Postcondition)
• 不変条件(Invariant)
13年3月11日月曜日
- 15.
契約による設計
• 事前条件
• サブルーチンの開始時に満
たされるべき条件
• 呼び出し側が守ること
13年3月11日月曜日
- 16.
契約による設計
• 事後条件
• サブルーチンの終了時に保
証されるべき条件
• 実装側が守ること
13年3月11日月曜日
- 17.
契約による設計
• 不変条件
• 公開している操作の実行後
に常に保証されるべき条件
• 実装側が守ること
13年3月11日月曜日
- 18.
- 19.
詳しくは
••
@t_wadaさんの
http://www.slideshare.net/t_wada/exception-
design-by-contract#btnPrevious
13年3月11日月曜日
- 20.
- 21.
言語標準な言語
• Eiffel
• Bertrand Meyer氏考案
• D言語
13年3月11日月曜日
- 22.
Java
• 標準
• assert文
• ライブラリ
• Contract4J, cofoja
13年3月11日月曜日
- 23.
Groovy
• 標準
• assert文(PowerAssert)
• ライブラリ
• GContracts
13年3月11日月曜日
- 24.
GContracts
• Andre Steingress氏による
契約プログラミング用のラ
イブラリ
• https://github.com/
andresteingress/
13年3月11日月曜日
- 25.
GContracts
• アノテーションにより満た
すべき条件をコード中に記述
• 条件のコード内容は
GroovyDocに出力可能
13年3月11日月曜日
- 26.
GContracts
• 事前条件 -> @Requires
• メソッドに指定
• 事後条件 -> @Ensures
• メソッドに指定
• 不変条件 -> @Invariants
• クラスに指定
13年3月11日月曜日
- 27.
GContracts
• 各条件をクロージャで記述
• 契約に違反した場合、
PowerAssertでエラー出力
13年3月11日月曜日
- 28.
GContracts
• @Ensuresのクロージャ内
では、次の値を参照できる
• old : メソッド実行前の状
態。Map
•
13年3月11日月曜日
result : 実行結果
- 29.
GContracts
• 各条件を継承
• 各条件をクラスだけでなく
インタフェースにも指定可
13年3月11日月曜日
- 30.
GContracts
import 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日月曜日
- 31.
- 32.
やってること
• 3行で言うと...
13年3月11日月曜日
- 33.
やってること
• 3行で言うと...
• AST変換で
13年3月11日月曜日
- 34.
やってること
• 3行で言うと...
• AST変換で
• 条件用のコードを
13年3月11日月曜日
- 35.
やってること
• 3行で言うと...
• AST変換で、
• 条件用のコードを、
• コンストラクタとメソッド
に埋め込み
13年3月11日月曜日
- 36.
やってること
• 3行で言うと...
• AST変換で、
• 条件用のコードを生成、
• コンストラクタとメソッド
に埋め込み、
• 実行する。
13年3月11日月曜日
- 37.
AST変換
• Abstract Syntax Tree変換
• 抽象構文木をこねくりまわ
す
13年3月11日月曜日
- 38.
AST変換
• サービスプロバイダ機能を使って、次の
ASTTransformationの実装クラスを指
定。
• org.gcontracts.ast.ClosureExpressionE
valuationASTTransformation
• org.gcontracts.ast.GContractsASTTran
sformation
13年3月11日月曜日
- 39.
- 40.
import org.gcontracts.annotations.*
@org.gcontracts.annotations.Invariant(value= Rocket$_gc_closure1)
@org.gcontracts.annotations.Contracted
public 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日月曜日
- 41.
final public classRocket$_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 nn' + error.getMessage())
newError.setStackTrace(error.getStackTrace())
}
finally {
}
return $_gc_closure_result
}
// (省略)
}
13年3月11日月曜日
- 42.
final public classRocket$_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.Req
uires> Rocket.void accelerate() nn' + error.getMessage())
newError.setStackTrace(error.getStackTrace())
}
finally {
}
return $_gc_closure_result
}
// (省略)
}
13年3月11日月曜日
- 43.
final public classRocket$_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.En
sures> Rocket.void accelerate() nn' + error.getMessage())
newError.setStackTrace(error.getStackTrace())
}
finally {
}
return $_gc_closure_result
}
// (省略)
}
13年3月11日月曜日
- 44.
- 45.
- 46.
- 47.
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日月曜日
- 48.
// 事後条件
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.En
sures> Rocket.void accelerate() nn' + error.getMessage())
newError.setStackTrace(error.getStackTrace())
throw newError
}
finally {
}
}
}
// 不変条件
this.invariant_Rocket()
}
13年3月11日月曜日
- 49.
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日月曜日
- 50.
- 51.
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日月曜日
- 52.
$GCONTRACTS_ENABLED
• メソッドの呼び出しごとに条
件が評価されるのは遅い
• $GCONTRACTS_ENABLED
で実行を制御する
• -ea,-daVMパラメータで指定
13年3月11日月曜日
- 53.
3 09, 20134:56:21 午後 org.codehaus.groovy.runtime.StackTraceUtils
sanitize
WARNING: 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(Script
BytecodeAdapter.java:655)
! at A.process(ConsoleScript30:22)
13年3月11日月曜日
- 54.
Exception thrown
3 09,2013 4:50:36 午後 org.codehaus.groovy.runtime.StackTraceUtils
sanitize
WARNING: 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(Script
BytecodeAdapter.java:655)
! at Rocket.accelerate(ConsoleScript29:8)
13年3月11日月曜日
- 55.
- 56.
まとめ
• 原本を読んでね。
• 使ってみてね。
13年3月11日月曜日
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.