Xtend30分クッキング

  • 1,116 views
Uploaded on

Xtendを30分程度で料理します。

Xtendを30分程度で料理します。

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
1,116
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
10
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Xtend30 分 クッキング
  • 2. Xtend30 分 クッキング
  • 3. ITS JUST Java
  • 4. Xtend Extends Java
  • 5. 愛 は 関 ジャバ にある。
  • 6. Xtend30 分 クッキング
  • 7. Java ソースへ変換拡張メソッドローカル型推論ステートメントレス(全てが式)強力な Switch 式ラムダ演算子上書きテンプレート式プロパティ
  • 8. Xtend news! JavaOne 2012Xtend at JavaOne 10/2 10:00 Sebastians プレゼンテーション on Xtend
  • 9. Xtend 30 分 クッキング愛 は X tend にある。 関ジャバの提供でお送りします。
  • 10. 先生のレシピ 先生のレシピ @s_kozake 先生 s_kozake せんせい Xtend 研究家・トラブル火消士。 某大学卒業後、某大手 SIer 企業での下積み ( 常駐 ) を経て 自社のビックプロジェクトに従事するに至る。 2 人の娘さんの父親でもあり、過酷な育児の日々の中、 「 No ドラクエ No ライフ」を嫁に提案中。著プレゼン / LT (http://www.slideshare.net/s_kozake)「 Play! Together 」( Play Framework 勉強会 in 関西)「 About Jobs 」(やきに駆動 秋の Java 祭典スペシャル in 大阪~こりん星)「 MyBatis で流れるようなメソッドチェーン」(やきに駆動 秋の Java 祭典スペシャル in 大阪~こりん星)「システムアーキテクトになる前に覚えておきたい技術とか色々」(鹿駆動勉強会)「たのしい関数型」(第 1 回 関数型言語勉強会 大阪)著ブログ (http://ameblo.jp/kozake)「はじめての変態」(変態アドベントカレンダー 2011 )「変態アドベントカレンダー 2011 の QR コード作りました」(変態アドベントカレンダー 2011 )「 cron4j のご紹介」( Java Advent Calendar 2011 )「 Play Excel !」( Play! framework Advent Calendar 2011 )「おめでたい話と悩みごと」(変態アドベントカレンダー 2011 )
  • 11. 本日のレシピ『 Xtend 』
  • 12. Whats Xtend?Java ランタイムに完全な互換性をもつ、ラムダを備えた Java 互換言語Xtext という DSL ライブラリおよびエディタ生成のためのプラグインスイートをベース
  • 13. Xtend のコンセプト Python や Ruby と同等の表現力 互換性問題のない Java Java の構文とコンセプトをできるだけ再利用 Java アプリケーションを読みやすく表現力高く
  • 14. Xtend は Java のソースファイルを生成する Java バイトコード 0: aload_0 1: invokespecial 4: return 0: getstatic 3: ldc #3; 5: invokevirtual 8: return Java ソースコード Java バイトコード import org.eclipse.xtext.xbase.lib.InputOutput; 0: aload_0 1: invokespecial public class HelloWorld { 4: return public static void main(final String[] args) { 0: getstatic InputOutput.<String>println("Hello World"); 3: ldc #3; } 5: invokevirtual } 8: return要するに、 Java にとっての「 CoffeeScript 」
  • 15. Xtend のコンパイル方法・ Eclipse ビルダ経由・ Maven プラグインコンパイラは Eclipse とは完全に独立
  • 16. Xtend の機能拡張メソッドローカル型推論ステートメントレス(全てが式)強力な Switch 式ラムダ演算子上書きテンプレート式プロパティ
  • 17. Why Xtend?ITS JUST Java Java 技術者の習得コストが少ない =技術者確保が容易 Java の既存資産が活用できる 静的型付けであり、 Java と同等の性能
  • 18. Why Xtend?DSL 拡張メソッド、演算子上書き、 テンプレート式など、内部 DSL を作成する 便利機能がそろっている
  • 19. 下ごしらえ( Installation )
  • 20. Xtend <1 人分 >Eclipse Juno ---------------------------1 DownloadXtend-2.3.1 ----------------------------1 DownloadWindows7 -----------------------------1 ライセンスコーヒー ------------------------------5 ~ 10 本嫁の理解 ------------------------------2 人日やる気 --------------------------------- 少々
  • 21. Help → Install New Software
  • 22. 下の URL を入力し、 Xtend-2.3.1 を選択。http://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases/
  • 23. Next
  • 24. Check 「 I accept.. 」 → Finish
  • 25. Download.... → restart
  • 26. New → Java Project
  • 27. Input Project name → Next
  • 28. Add Library
  • 29. Select 「 Xtend Library 」→ Next
  • 30. Finish
  • 31. 試食( Demo )
  • 32. Demo ソース「 Hello World 」HelloWorld.xtendpackage democlass HelloWorld { def static void main(String... args) { println(Hello World!) }} HelloWorld.java package demo; import org.eclipse.xtext.xbase.lib.InputOutput; @SuppressWarnings("all") public class HelloWorld { public static void main(final String... args) { InputOutput.<String>println("Hello World!"); } }
  • 33. Demo ソース「 FizzBuzz 」FizzBuzz.xtend FizzBuzz2.xtendpackage demo package democlass FizzBuzz { class FizzBuzz2 { def static void main(String... args) { def static void main(String... args) { } new FizzBuzz().run More } new FizzBuzz2().run; Simple def void run() { def void run() { var i = 1 (1..100).forEach [ println(it.fizzbuzz) ] while (i <= 100) { } println(fizzbuzz(i)) i = i + 1 def fizzbuzz(int i) { } switch i { } case (i % 15 == 0) : fizzbuzz case (i % 3 == 0) : fizz def String fizzbuzz(int i) { case (i % 5 == 0) : buzz if (i % 15 == 0) { default : i.toString return fizzbuzz } } else if (i % 3 == 0) { } return fizz } } else if (i % 5 == 0) { return buzz } else { return String::valueOf(i) } }}
  • 34. Demo テストソース「 FizzBuzz2Test 」FizzBuzz2Test.xtendpackage demoimport static org.junit.Assert.*;import static org.hamcrest.CoreMatchers.*;import org.junit.Testclass FizzBuzz2Test { extension FizzBuzz2 test = new FizzBuzz2() @Test def testFizzBuzz() { assertThat (1.fizzbuzz, is(1)) assertThat (3.fizzbuzz, is(fizz)) assertThat (5.fizzbuzz, is(buzz)) assertThat (15.fizzbuzz, is(fizzbuzz)) }}
  • 35. 調理(機能紹介)
  • 36. Xtend の機能拡張メソッドローカル型推論ステートメントレス(全てが式)強力な Switch 式ラムダ演算子上書きテンプレート式プロパティ
  • 37. 拡張メソッド既存の型に変更なしに新しいメソッドを追加できます。Xtend の名前はこの機能からきています。機能自体は単純な仕組み拡張メソッドの最初のパラメータを渡す代わりにそのメンバの 1 つであるかのようにメソッドが呼ばれます。 15.fizzbuzz // call fizzbuzz(15)
  • 38. 拡張メソッド(利点)ネストされたメソッド呼び出し(コマンドクエリー IF )でなくチェインされたメソッド呼び出し(流れるような IF )が可能可読性が増します。JsonUtil::writeJson(obj) でなくobj.writeJson特定のコンテキストやアプリケーション層に固有メソッドを追加できます。
  • 39. 拡張メソッド(組み込みライブラリ)デフォルトで既存クラスの拡張メソッドが用意されています。・ ObjectExtensions・ IterableExtensions・ MapExtensions・ ListExtensions・ CollectionExtensions・ BooleanExtensions・ IntegerExtensions・ FunctionExtensions val obj = newArrayList(1,2,3) println(obj.map[it * 2]) // [2, 4, 6] println(obj.getClass.getName) // java.util.ArrayList
  • 40. 拡張メソッド(ローカル Extension インポート)クラス内または親クラスの可視性のある非 static メソッドは自動的に拡張メソッドとして使えます。 def void run() { println(15.fizzbuzz) } def fizzbuzz(int i) { switch i { case (i % 15 == 0) : fizzbuzz case (i % 3 == 0) : fizz case (i % 5 == 0) : buzz default : i.toString } }
  • 41. 拡張メソッド( Extension インポート)ヘルパークラスなどが用意する static メソッドは、import static の後ろに extension キーワードを配置することで、全ての static メソッドを拡張メソッドとしてimport できます。 package demo import static org.junit.Assert.*; static import static org.hamcrest.CoreMatchers.*;package demo Import import static extension demo.JsonUtil.*; extensionclass JsonUtil { import org.junit.Test def static writeJson(Object obj) { println(obj.toString) class TestJsonUtil { }} @Test def void testWriteJson() { val obj = test obj.writeJson } }
  • 42. 拡張メソッド( Extension フィールド)フィールド定義に extension キーワードを追加すると、そのインスタンスのメソッドは拡張メソッドとなります。class FizzBuzz2Test { extension FizzBuzz2 test = new FizzBuzz2() @Test def testFizzBuzz() { assertThat (1.fizzbuzz, is(1))       : }}static な extension import と比べて、フィールド定義によるextension の利点は、実装にバインドされないことです。factory や依存性注入、 setter メソッドにより外部から実装を簡単に交換できます。
  • 43. Xtend の機能拡張メソッドローカル型推論ステートメントレス(全てが式)強力な Switch 式ラムダ演算子上書きテンプレート式プロパティ
  • 44. ローカル型推論変数の型は右の式から推論されます。また、メソッドの戻り値もメソッド本体から推測されます。 package demo; import java.util.Date; package demo @SuppressWarnings("all") import java.util.Date public class DemoClass { private final int a = 1; class DemoClass { val a = 1 private String b = "test"; var b = test public var c = 2 public int c = 2; def hoge() { public String hoge() { val d = new Date String _xblockexpression = null; hoge { } Date _date = new Date(); } final Date d = _date; _xblockexpression = ("hoge"); } return _xblockexpression; } }
  • 45. Xtend の機能拡張メソッドローカル型推論ステートメントレス(全てが式)強力な Switch 式ラムダ演算子上書きテンプレート式プロパティ
  • 46. ステートメントレス(全てが式)Xtend はステートメントを持っていません。全てが式で戻り値を持っています。全ての式を紹介する時間がないので、いくつかの式を紹介します。
  • 47. ステートメントレス( if 式)if (p) e1 else e2if は p の結果により e1 か e2 を返す式です。val a = if (true) 1 else 2println(a) // 1else をオプションで省略可能です。val a = if (false) 1val b = if (false) aprintln(a) // 0println(b) // null
  • 48. ステートメントレス( for 式)for (T1 variable : arrayOrIterable) expressionfor は void を返す式です。variable の型は arrayOrIterable の型から型推論されるので省略可能です。val arr = newArrayList(1,2,3,4,5)for (i : arr) { println(i)}
  • 49. ステートメントレス( try-catch 式) try-catch も式です。以下のようなコードを書くことで 今まで必要だったローカル変数を省略できます。 val s = a val n = try { Integer::parseInt(s) } catch (NumberFormatException ex) { -1 } println(n) // -1
  • 50. ステートメントレス(その他)ローカル変数 it を使用すると、 it に代入されたインスタンスのフィールドやメソッドがローカルのように扱えます。 package demo class Hoge { @Property String fuga } class DemoClass { def static void main(String... args) { val it = new Hoge fuga = test println(fuga) // test } }
  • 51. ステートメントレス(その他)?. によるメソッド呼び出しで、 null 安全な呼び出しが可能です。 var hoge = new Hoge Hoge _hoge = new Hoge(); hoge?.hello Hoge hoge = _hoge; if (hoge!=null) hoge.hello(); hoge = null hoge = null; hoge?.hello if (hoge!=null) hoge.hello();
  • 52. ステートメントレス(その他)Static アクセスは . でなく :: でアクセスします。 val n = Integer::parseInt(1) println(n)
  • 53. Xtend の機能拡張メソッドローカル型推論ステートメントレス(全てが式)強力な Switch 式ラムダ演算子上書きテンプレート式プロパティ
  • 54. 強力な Switch 式 Switch 式は Java の switch 文とはかなり異なっています。  ・下への落下がない  ・特定の値に限定されず、任意のオブジェクトが使用可能 val s = ho val ret = switch s + ge { case s.length > 5 : so long case hoge : equal hoge default : not } println(ret) // equal hoge まず、 switch の式が評価されます。 式の型が boolean 型なら、 true で case にマッチします。 boolean 型以外なら、 Object.equals(Object) が比較に使用されます。 case にマッチしたら、コロンの後の式が評価され、式全体の結果となります。
  • 55. 強力な Switch 式 ケースガードに加え、型ガードもサポートしています。 def length(Object x) { switch x { String case x.length > 0 : x.length // length is define String List<?> : x.size // size is define for List default : -1 } } switch の値が型と一致しているのみ、ケースと比較します。 型と一致しない場合、 case の式は評価されません。 両方が一致した場合、コロンの後の式が評価されます。 switch の値が変数の場合、自動的にその型にキャストされます。 Java の instance of やキャストに比べて読みやすく型安全です。
  • 56. Xtend の機能拡張メソッドローカル型推論ステートメントレス(全てが式)強力な Switch 式ラムダ演算子上書きテンプレート式プロパティ
  • 57. ラムダXtend は SAM(Single Abstract Method) Type のインタフェースをラムダ式として表せます。 public interface Hello { class DemoClass { void hello(String s); } def static void main(String... args) { helloWorld([String s | println(s)]) } def static void helloWorld(Hello o) { o.hello(hello world!) } }上記のように角括弧で囲んだ部分がラムダ式です。この構文は、 Smalltalk に影響を受けたらしいです。| の区切りでパラメータ宣言と式が書かれています。
  • 58. ラムダ public interface Hello { class DemoClass { void hello(String s); } def static void main(String... args) { helloWorld([String s | println(s)]) } def static void helloWorld(Hello o) { o.hello(hello world!) } }パラメータの型はインタフェースの型から推測できるので、省略可能です。
  • 59. ラムダ public interface Hello { class DemoClass { void hello(String s); } def static void main(String... args) { helloWorld([println(it)]) } def static void helloWorld(Hello o) { o.hello(hello world!) } }パラメータが 1 つの場合、パラメータ宣言が省略可能です。省略した場合、パラメータは it という名前の変数にバインドされます。
  • 60. ラムダ public interface Hello { class DemoClass { void hello(); } def static void main(String... args) { helloWorld([| println(hello world!)]) } def static void helloWorld(Hello o) { o.hello() } }パラメータないメソッドは上記のように書けます。| の記述がいることに注意してください。
  • 61. ラムダ public interface Hello { class DemoClass { void hello(String s); } def static void main(String... args) { helloWorld(3) [ println(it) ] } def static void helloWorld(int n, Hello o) { (1..n).forEach [ o.hello(hello world!) ] } }メソッド一番右側のパラメータがラムダ式の場合、パラメータリストの後に渡すことができます。
  • 62. ラムダ public interface Hello { class DemoClass { void hello(String s); } def static void main(String... args) { val name = duke helloWorld [ println(it + + name) ] } def static void helloWorld(Hello o) { o.hello(hello world!) } }Java 同様、ラムダ式の外部の final 変数参照することが可能です。
  • 63. ラムダSAM Type がなくても、下記のように書けます。 val f = [int n | n**3 ] println(f.apply(2)) // 8.0 final Function1<Integer,Double> _function = new Function1<Integer,Double>() { public Double apply(final Integer n) { double _power = Math.pow(n, 3); return _power; } }; final Function1<Integer,Double> f = _function; Double _apply = f.apply(Integer.valueOf(2)); InputOutput.<Double>println(_apply);戻り値が void の場合、 Procedures 、それ以外は Functions となります。
  • 64. ラムダXtend は関数型の簡略構文もサポートしています。 val (int) => double f = [int n | n**3 ] println(f.apply(2)) // 8.0 = val Function1<Integer,Double> f = [int n | n**3 ] println(f.apply(2)) // 8.0
  • 65. Xtend の機能拡張メソッドローカル型推論ステートメントレス(全てが式)強力な Switch 式ラムダ演算子上書きテンプレート式プロパティ
  • 66. 中置演算子と演算子のオーバーロードJava とは対照的に、演算子は特定の型の操作に限定されません。任意の型の演算子を再定義し、対応するメソッドシグネチャを実装することで、演算子からメソッドへのマッピングが可能です。例えば、ランタイムライブラリには、 BigDecimal の演算子を定義するクラス BIgDecimalExtensions が含まれています。val a = 1BDval b = 2BDprintln(a.getClass.getName) // java.math.BigDecimalprintln(b.getClass.getName) // java.math.BigDecimalprintln (a + b) // 3
  • 67. 中置演算子と演算子のオーバーロード演算子のオーバーロードが可能です。package demo@Dataclass DemoClass { String hoge def DemoClass operator_add(DemoClass obj) { new DemoClass(this.hoge + obj.hoge) } override toString() { hoge } def static void main(String... args) { val a = new DemoClass(hoge) val b = new DemoClass(fuga) println(a += b) // hogefuga }}
  • 68. 中置演算子と演算子のオーバーロード使用可能な演算子とそれに対応するメソッドシグネチャの完全なリストです。また、下の表は昇順で演算子の優先順位を定義しています。e1 += e2 e1.operator_add(e2)e1 || e2 e1.operator_or(e2)e1 && e2 e1.operator_and(e2)e1 == e2 e1.operator_equals(e2) e1 <> e2 e1.operator_diamond(e2)e1 != e2 e1.operator_notEquals(e2) e1 ?: e2 e1.operator_elvis(e2)e1 < e2 e1.operator_lessThan(e2) e1 <=> e2 e1.operator_spaceship(e2)e1 > e2 e1.operator_greaterThan(e2) e1 + e2 e1.operator_plus(e2)e1 <= e2 e1.operator_lessEqualsThan(e2) e1 – e2 e1.operator_minus(e2)e1 >= e2 e1.operator_greaterEqualsThan(e2) e1 * e2 e1.operator_multiply(e2)e1 -> e2 e1.operator_mappedTo(e2) e1 / e2 e1.operator_divide(e2)e1 .. e2 e1.operator_upTo(e2) e1 % e2 e1.operator_modulo(e2)e1 => e2 e1.operator_doubleArrow(e2) e1 ** e2 e1.operator_power(e2)e1 << e2 e1.operator_doubleLessThan(e2) ! e1 e1.operator_not()e1 >> e2 e1.operator_doubleGreaterThan(e2) - e1 e1.operator_minus()e1 <<< e2 e1.operator_tripleLessThan(e2)e1 >>> e2 e1.operator_tripleGreaterThan(e2)
  • 69. Xtend の機能拡張メソッドローカル型推論ステートメントレス(全てが式)強力な Switch 式ラムダ演算子上書きテンプレート式プロパティ
  • 70. ごめんなさい手がまわりませんでした (><)
  • 71. Xtend の機能拡張メソッドローカル型推論ステートメントレス(全てが式)強力な Switch 式ラムダ演算子上書きテンプレート式プロパティ
  • 72. プロパティフィールド変数を @Property アノーテーション定義することでsetter / getter を自動生成してくれます。 @SuppressWarnings("all") public class DemoClass { private String _hoge;class DemoClass { public String getHoge() { @Property return this._hoge; String hoge }} public void setHoge(final String hoge) { this._hoge = hoge; } }フィールドが指定されたコンテキストからアクセスできない場合、 setter が使用されます。これが @Property アノーテーションがローカルフィールドを_myProperty にリネームする理由です。
  • 73. プロパティまた、クラス定義に @Data アノーテーション定義することで値オブジェクトとしてクラスを定義できます。 import org.eclipse.xtend.lib.Data; import org.eclipse.xtext.xbase.lib.util.ToStringHelper; @Data @SuppressWarnings("all") public class DemoClass { private final String _hoge; @Data public String getHoge() { class DemoClass { return this._hoge; } String hoge public DemoClass(final String hoge) { } super(); this._hoge = hoge; } @Override public int hashCode() { : @Override public boolean equals(final Object obj) { : @Override public String toString() { : }
  • 74. まとめ
  • 75. Xtend Extends Javaモダンな言語機能を備えている。 ・ラムダ ・型推論 ・強力な Switch 式 ・ etc..既存機能を拡張できる ・拡張メソッド
  • 76. ITS JUST Java既存のリソースを活用できる ・豊富な OSS ・ IDE サポート ・様々な経験知 ・ etc..なによりも・・・ Java である
  • 77. 30 分 Xtend クッキング Thank you a lot 愛 は Java エンジニア にある。 関ジャバの提供でお送りしました。