[vim] 自分用メモ

埋め込みgistやってみたら markdownがそのまんまなので、gistを直接見た方がよいです。忘れたくない便利なコマンドを覚えたら追加する予定

VIMのコマンド備忘録(自分用)

  • 自分のよく使うもの
  • 自分の忘れやすいもの
  • 網羅的ではない。自分用メモ

view raw

readme.md

hosted with ❤ by GitHub

カーソル移動系

  • 後で書く

編集系

  • r: カーソル位置の1文字を変更

  • x: カーソル位置の1文字を削除

  • s: カーソル位置の1文字を入力文字(n文字)に変更

  • cw: カーソル位置から始まる単語を入力文字に変更

  • dw: カーソル位置から始まる単語を削除

  • dd: カーソル位置の行(全体)を削除

  • D: カーソル位置以降、行末まで削除

  • dG: カーソル位置からファイルの最後までの行削除

  • ~: カーソル位置の1文字を大文字/小文字に変換

  • yy: カーソル行をコピー(yank)

  • p: コピー(yankまたは削除したもの)を貼付

  • u: undo

  • Ctrl+r: redo

  • .: 前回実行コマンドを再実行

一括置換系

  • :%s/_regexp_/_replace_/: 正規表現 regexp を_replace_に置換
  • :%s/_regexp_/_replace_/g: 末尾/g (グローバル)で各マッチ箇所を置換。指定なしの場合は各行の最初のマッチ箇所だけ置換
  • :%s/_regexp_/_replace_/c: 確認モードで正規表現 regexp を_replace_に置換。/gcのように組み合わせることも可能
  • :%s/_regexp_/d: 正規表現 _regexp_にマッチする行を削除
  • :1,3s/_regexp_/_replace_/: 行番号1~3の中で正規表現 regexp を_replace_に置換。末尾に/g/dを指定可能

view raw

vim_edit.md

hosted with ❤ by GitHub

タブ系

  • :tabe _filename_: 新しいタブで filename を開く
  • :tab all: 開いているファイルを全てタブとして開く
  • :tabs: 現在開いているタブを一覧表示
  • gt: 次のタブに移動
    • 応用 4gt: 4つ右のタブに移動
  • gT: 前のタブに移動
  • :q: 現在のタブを閉じる
  • :qa: 全てのタブを閉じる

応用例

  1. vim somefiles*.txt 複数のファイルを開く
  2. :tab all で全てタブで開く
  3. :tabs でタブ一覧を確認
  4. 3gt で目的のタブに移動(gtの前の数字で移動回数を指定する)

view raw

vim_tabs.md

hosted with ❤ by GitHub

Scala Conference in Japan 2013 に行ってきました

Scala Conference in Japan 2013に行ってきました。

技術的な話はスキル的にできないので、感想というか印象にのこったことを書きます。


これです。

まさに「10年くらいまえのJavaの熱気」でした。
自分語りみたいになりそうですが、かつて C++を書いていた頃の自分にとっての Javaと、いま Javaを書いている自分にとっての Scala。これらがとてもカブって感じるのです。書籍から引用してこれを代弁してもらいます。

1995 年にJava が現れたとき、Java は、ポインタやメモリ管理、その他の難解な配管工事のような仕事と戦い疲れたC++ プログラマを救済する言語として歓迎されました。Java は、そうしたプログラマの難題を解決してくれました。

しかし、2008 年現在、もはや下位互換性は意味がありません。

Java は、0 で始まる配列のようなC++ 主義や、プリミティブ型とオブジェクトの区別などの 1995 年には意味があったけれども最近の開発者の生産性に役立たないお荷物であふれかえっています。
ThoughtWorksアンソロジー P55

ちなみに 「かつての自分」は’95年じゃないですよ。大体10年くらいまえですね。若い人は最初からJavaだったりrubyだったりしますからオッサンホイホイ的エントリの予感です。

Scalaは Java VMで動作し、既存のJavaのライブラリを利用できますので「Javaな人」向けの Better Javaという位置にいます。カンファレンスで発表された竹添さんも、既存の資産を利用したいので Playは Servletでも動いてほしい、そういうニーズがあるということをおっしゃってましたね。

さて、Javaは次のような戦略をとりました。

しかし、Javaの成功のためには、当時の開発者にとって高位の聖職者ともいえるC++ 開発者にアピールする必要がありました。したがって、Java の設計者が意図的にJava 言語の見た目をC++ に似せたことには意味がありました。もう一度基礎からすべてを学び直さなければならないとしたら、開発者を新しい言語に引きつけることはできませんから。
ThoughtWorksアンソロジー P55

(当時 CっぽいC++を量産していた自分は聖職者ではありませんでしたが。)

それからJavaの父、James Gosling氏も言ってますね。

Javaと Javaの ASCIIコードレベルの構文は、Cプログラマや C++プログラマが簡単に使えるように設計されています。実際、とてもうまくいっています。ほとんどの Cプログラマや C++プログラマは Javaコードを少し眺めてこう考えます。「うん、これはわかる。」ってね。

「我こそが考えうる最高のプログラミング言語だ」と自負している理論的な世界の場合は、相互移行性は現実の目標にはなりません。

もしも私がJava を離れて自分専用のプログラミング言語を設計したとしたら、きっとほとんどの人は怒り心頭でしょうね
言語設計者たちが考えること P306

つまりJavaの言語仕様は、理想形を目指したわけではなく最初からマーケティング的な割り切りがあったわけです。やはり企業生まれですし。
自分も、C++ → Javaの時と同じように、Javaの延長線上に Scalaが居ることをある程度期待しているのかな、と、気づきというかあらためて認識しました。
一方、Scalaは Better Javaだけでなく、関数型プログラミングという Javaにはないパラダイムも同時に実現しようとしています。なので、確かにJavaっぽく書けますが、Javaっぽくない(関数型っぽい)書き方もできます。その他にも強力な機能があって(理解していない機能も まだまだいっぱいあるし)、そういう Scalaコードだと自分にはまだ読めません。わかってしまえば簡単なのかもしれませんが、自分にとってはまだ謎コードも多いです。もちろん読めるようになりたいんですけど、演算子とか記号はググりにくいんですよね。

ところで先日、周りのJavaな人たちに自分のこのScala熱を浴びせてみたのですが、better Java以外のところについては、あまり反応がよくありませんでした。それで、Better Javaだけならば Groovyを使うという選択もありえますし、Java 8で型推論とラムダ式がサポートされたら Scalaに近いBetterが達成できるじゃないか、と。いや、自分がうまくそれ以外のところを説明できてないことによるものですが。

ということで、Scalaを推すときは、Better Javaだけでなく、関数型プログラミングとか、(カンファレンスで望月さんが発表された)Betterオブジェクト指向プログラミングとか、Javaよりもっと強力だってことをうまく説明できるようになりたいですね。スキル尚早だったかも。初心者の自分でも思いつくのは、trait, case class, Option, 代数的データ型、パターンマッチ、Javaより強力なジェネリクスやcollection framework。それから、関数型プログラミングの考え方、immutable, 抽象化, データ構造, 再起(書き方というより、再帰的な性質を見つける考え方とか)全然網羅的ではなく思いつくまま書いてますが、こまかくたくさんありますよね。
それから伝わらないかもしれませんが、プログラミング=処理を書くもの。という考え方から、プログラミング=問題解決。という考え方になってきた気がします。(少し大げさに言ってます:-p)
挙げればいくつもあるんですが、その素晴らしさをうまく言語化できると良いのですが…
なので、もっとまともに説明できるように勉強しないと、という話になって残念エントリになってしまいますね。。。
まぁ懐疑的な人も食わず嫌いせずに少し何かScalaで書いてみたら、日本語で説明されなくても、良さが分かるってこともあると思いますよ。

最後に

Scalaの普及には、それ自体の良さだけでなくてマーケティングはある程度必要なのかなぁと勝手に思ってます。
でも Scalaが必要以上に Javaユーザに媚びるようなこともして欲しくないし、ましてや 一時期の Agileのような、例えば「WFは悪!あいつらはいつも分厚い紙束のドキュメントを持ち寄って何時間も会議してる」みたいな煽りで「ああAgileはドキュメント書かなくていいのかー」みたいな誤解でもって広まったりもしてほしくないです。そういうのは、てっとり早く広まるかもしれないけど Agileの人たちはそんな誤解を解くコストを後から結構払ったわけで(でもだいぶそういう極端な誤解はなくなりましたけどね。煽ってた人とは別の人たちがずいぶんがんばったのではないでしょうか。)
もちろん、Scalaが普及してほしいんですけども。簡単にあーすればよいとか言えないですね。

Scalaのマーケティングとかどうこう言える立場でもないですが、そんなことを思ったのでした。

springframework profile機能について

Spring Framework 3.1あたりから追加された profile機能について軽く説明します。

profile機能とは、実行環境によって異なるJDBC接続プロパティなどを切り替えるための仕組みです。profile機能を使用すると 1つのapplication contextのxmlの中に、開発用、出荷時用の2つのプロファイルとして設定を記述し、実行時にどちらのプロファイルを有効化するかを指定することができます。

以下にxmlの例を書きます。この例は、開発時のUnitTestではin-memory-dbを使用し、出荷時のAPサーバにデプロイしたときはJNDIでDataSourceを取得するような場合の設定方法です。

プロファイル定義

下記のxmlの beans profile="development" と beans profile="production" を見てください。

	<beans profile="development">
		<jdbc:embedded-database id="dataSource" />
	</beans>
	<beans profile="production" >
		<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
	    	<property name="jndiName" value="java:comp/env/jdbc/DatabaseName"/>
		</bean>
	</beans>

それぞれの<beans>要素は、developmentプロファイルには in-memory-db (参考 Reference Documentation 13.8 Embedded database support)、productionプロファイルにはJNDIで取得するdataSourceを定義しています。

実行時に有効化するプロファイルの指定

springらしく(笑)、さまざまなやり方があります。(参考Spring 3.1 Environment Profiles | Technophile Blog)
ここではいくつかの例を挙げます。

アプリケーション実行時の指定

web.xmlによる指定

Servletの場合はweb.xmlで指定できます

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>spring.profiles.active</param-name>
        <param-value>production</param-value>
    </init-param>
</servlet>

System Propertyまたは環境変数による指定

java実行時に spring.profiles.activeにプロファイル名を指定できます

-Dspring.profiles.active=production

または

export spring_profiles_active=production

JUnitでの指定

JUnitで springの機能をテストするときに、@ActiveProfilesというアノテーションで、有効化するプロファイルを指定します。このコードではdevelopmentが有効化されるので、このテストのdataSourceは、in-memory-dbになります。

@ContextConfiguration(locations={"/application-context.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("development")
public class ProfileTest {
    @Autowired
    private DataSource dataSource;
}

(参考までに): 複数のプロファイル

複数のプロファイルを設定したり、複数のプロファイルを有効化して実行することができます。

複数プロファイルの設定

	<beans profile="integration,production" >
		<!-- integration,productionのいずれか1つが有効化されている場合に、ここのbean定義が使用されます -->
		<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
	    	<property name="jndiName" value="java:comp/env/jdbc/DatabaseName"/>
		</bean>
	</beans>

実行時の複数プロファイル有効化指定

-Dspring.profiles.active=production,apiV2,specialFeatureA

使ってみて思ったこと

経験上これまでspring frameworkを使ったプロジェクトは、xml設定ファイルのデバッグに多大な時間が費やされることが多かったです。しかもAPサーバにデプロイしないと動作しない設定が含まれていると非常にデバッグの効率が悪く、数日ハマることもありました。

profile機能を使うことで、UnitTestと製品用で一元的に設定したものを使用し、環境の差分のみをプロファイルで切り替えることができます。特にDB・トランザクションまわりの設定はシステム全体に関わるものなので、とある機能に必要な設定を追加した途端に、別の機能が動かなくなったりすることがspring frameworkではよく起きます。そういったことをUnitTestの段階で見つけることができるのは非常によいことです。たとえばJenkinsなどのCIサーバでUnitTestを走らせてフィードバックを常に得られていれば、設定関係の問題がデプロイしてから発生することは少なくなり、また発生しても問題箇所が限定的になるためデバッグ効率もこれより向上することが期待できるのではないでしょうか。

まとめ

profile機能は複数の異なる設定をプロファイルとして定義し、実行環境で有効化したい設定をプロファイルを指定することで切り替えることができます。

UnitTestと製品で同じ設定ファイルを使用していれば、設定ファイルに関係する問題の多くを早い段階で見つけることができるのです。

ORM嫌いについて

はじめに

Object-Relational Mappingツール・ライブラリ(以下、ORM)と言えば必ずといって良いほど誰かの不満の種デス。自分も使ってはいるけど不満はあります。ところで、あなたのご不満のORMとはなんのことを指してますか?そもそも、ORMという言葉は何の厳密な機能範囲も定義していないのですが、みんな過去にハマったライブラリの設定や自分のプロジェクトで使いにくかったことをもって「だからORMはダメだ」と主張している節もあると思います。下記のこの記事も(元ネタはBlikiですが)、ついてるコメントはみんなバラバラのことを指して不満点や解決案を書いています。
Martin Fowler on ORM Hate

自分にとってのORM

ORM vs SQLという対立軸で語られることもありますが、自分はSQL大好きですよ。宣言的でとても効率的に関係の操作を表現できる言語だと思います。

自分が現存するORMで期待しているところは、オブジェクトと行の詰め替え処理です。新しいオブジェクトのプロパティ値をINSERT文のVALUESに詰め替えたり、結果行の各カラム値をオブジェクトのプロパティに詰め替えたりするのは、誰がやっても同じになるコードをクエリごとに書かないといけないわけで、そこはライブラリの力を借りても良いところでしょう。

C#でLINQ to SQL(.NET4からはEntity Frameworkになったんでしたっけ?)を書いた時には、形安全クエリが書けることがうれしかったですね。静的型付け言語の経験が長いせいか、データベースのクエリでも型に対する誤りはコンパイラがチェックしてくれるということの安心感や、IDEがプロパティ名を補完してくれたり候補を表示してくれたりするのが思いのほか心地良かった。クエリを書く時にDDLファイルとか(あるいはテーブル定義書.xlsとか)を開いてテーブル名やカラム名をコピペしなくて良いのです。また、テーブル名やカラム名の変更も、IDEのリファクタリング機能で行えるのです。Javaも、8でラムダ式がサポートされたらこうなっていくでしょう。てか、scalaでできるよ、それ!

多分、自分はリレーショナルデータベース(関係代数演算)の操作がプログラミング言語にうまく統合されて欲しいのかもしれないですね。今はその手段として一番近い(まだ遠いけど)のがORMだというわけです。そりゃ、ORMの現状には不満がいっぱいあります。

ORMだと性能に問題アリですか?

性能の問題が起きた時にSQLクエリを直接さわれないと困るってよく言われることだと思います。
しかし、SQLを直接書いたからといって、性能の問題が起きないSQLクエリなんてあるんでしょうか。
SQLは宣言的な言語であり、クエリは「このような結果(What)をください」と記述します。DBMSはそのクエリをどのように(How)実行するか制御します。クエリ実行にあたっては、一番レコードを絞り込めるWHERE条件や件数の少ないテーブルの結合から実行すると速いとか、件数少ないテーブルはINDEX領域を取得してからより実レコード領域を直接取得するほうがIOを節約できるとか考えなくてはいけませんが、そういったことは DBMSにおまかせできます。その反面、DBMSが判断を誤るとクエリ実行時間が爆発することもあります。
このようなこともあり、Oracleではヒント句というのが用意されてますが、Oracleがクエリ実行計画を立てる時の統計情報を正しく保つように運用することが推奨されてます。

宣言的な言語は、機能的に動作させるまでが早い反面、いま言ったように性能的に効率良く動作させるためにはその実行系をチューニングして、速くなるよう仕向けるような間接的な作業をしなくてはいけません。でもそれってもう普通ですよね。みんな例えばメモリ領域をどう確保していつ解放するなんて直接書かずに ガベージコレクタ(GC)のパラメータでチューニングする言語・実行系を使ってるんじゃないですか?
もちろんGCのような機能はあらゆる処理で最速に動作することのは不可能なので、大抵の処理でそれなりに速いというところを狙ってて、実行環境によって違うところはパラメータでチューニング可能にしていると思います多分。それでもダメな場合はNativeコードを併用する必要性も出てきます。しかし、その場合でも、システムのあらゆるコードを1から10まですべてNativeコードでメモリ管理を明示的に書くべきとは思いません。性能問題が起きないようにすべてのSQLにヒント句をいれることを強制するプロジェクトとか、ORMをやめてSQLを書くべきだとかいうのは、それと同じものを感じます。
そして大抵のORMライブラリでは、DBMSのNativeなSQLを発行する機能があります。ORMかSQLかの2択などではなく、必要な時に必要なものを使い分ければ良いのです。

抽象化とバカ量産説

かつて(いまでも?)GCが「メモリ管理ができない低能プログラマを量産する」と言われたように、ORMとSQLにも同じ指摘があります。ある意味では、自分もコンパイル言語のせいで生み出された、マシン語が読めない低能プログラマということになります。
自分の場合は再帰処理のコールスタックくらいは意識しますが、書いたプログラムの1から10まで常に意識しなくてすむのはありがたいことです。仮に2割くらいはそういったローレベルを意識しているとして、でも残りの8割は脳みそ空っぽで過ごしているかというとそんなことはありません。その時間のほとんどは、自分のコードの問題領域(ドメイン)をどのように解決すべきかを考えるのに費やしているはずです。
より高度化するドメインの複雑さを解決することに集中できる道具なのであれば、自分は積極的に受け入れたい派です。コンピュータリソースが高性能化かつ廉価になり、実行系やツールの進化もあれば、高度化するニーズや複雑化する問題領域の解決に応えられなければならないでしょう。

最後に

ORM嫌いについてというタイトルですが、嫌い・不満の理由はひとによって様々あり、それらを網羅的にひとつの記事で書くつもりはありません。今回は、自分の観測範囲でよくありそうなアンチORMの主張を書いてみました。
ローレベルであれば「出来ないこと」は少なくなるということで、それを万能であると言うのは、それは「万能」包丁みたいな意味であり、目的に特化したらもっと良い方法あるよってことです。
そしてコンピュータリソースの高性能化や、実行系やツールの進化は、よりハイレベルの万能機能を産んでいくでしょう。いまはそうでなくても、長期的にはそういう流れはあると思います。そうしてプログラマは楽になるかというとそうではなくて、システムやサービスが価値を産むための仕事にとりかかれるようになるということです。

[ORM][Java] JavaのORMをいくつか比較してみる

昼間のお仕事の関係でORMをいくつか触ったので、比較してみることにした。今更なーという感じはするけど、現時点で選ぶなら何なのだろうかと考える人の一助になれば。

※ 2012/09/18 改訂。Spring DATA JPAと QueryDslについては詳細をGistにあげたので、リンクを貼りました。

  • Java Persistence API (JPA)
    • JSR-317. 一応JavaEE6の標準になっているが、使いやすいわけではなく補助的に組み合わせて使うライブラリがいくつか存在するのでそれらについて後述。
    • 大まかに、クエリを書く方法は2通り
      • JPQL(SQLに似非の独自クエリ言語)を文字列で書く
        • 例: select o from Order o where o.date < '2012-09-01'
      • Criteria API(メタクラスを生成すればある程度は型安全だが、APIが使いにくい)で書く
        • クエリ言語として流れるように書けないため、表現力が低い
        • これを解決するのが後述するQueryDsl。Blog記事が参考になる。
  • Spring DATA JPA
    • Spring Frameworkの拡張ライブラリ(springframework-jdbcシリーズのようだが、安定したら本流に組み込まれるのかもしれない)
    • Gistに詳しく書いてみました。こちら
  • QueryDsl(JPA)
    • Open Sourceのライブラリ。クエリを型安全で流れるようなインタフェースなDSLで記述することができるライブラリで、JPAのCriteria APIに変換するDSLと、直接SQLに変換するDSLとがある。後者はQueryDsl(SQL)として後述。
    • 前者のJPAのCriteria APIに変換するDSLについては、QueryDslの Blog記事を参照のこと。コードを見てもらえば、これ以上特筆することはない。
    • ちなみに更新系のinsert, update, delete処理は、JPAのEntityManagerのAPIをそのまま使用する
  • QueryDsl(SQL)
    • QueryDSL(SQL)については Gistに詳しく書いてみました。こちら
  • Spring DATA JDBC Extension
    • Spring JDBCの拡張ライブラリ。上述の Spring DATA JPAともまた別モノ。
    • Spring JDBC本体の JdbcTemplate から QueryDslの型安全クエリを生成できるが、流れるように書けないという残念なAPI。
    • 上記QueryDsl(SQL)の説明Gistに一緒に書きました。

 

ここに挙げたライブラリの動作確認コードは、 githubに上げてます。

総合評価的なマトリクスは昼間のお仕事でそのような流れになったら作成する予定。いま選ぶとしたら個人的には QueryDsl(JPA)かなぁ。

それから、実行時性能を比較するためにベンチマークのテストを仕込んでいるところ。これについては後日書く予定。

[gradle] Java6 Annotation Processing

  • QueryDsl(JPA)を例に GradleでAnnotation Processingを実行させてみる
  • antの例があるので、ほぼこのままだったりするけど。。

annotation processingとは

dependenciesの設定

  • Annotation Processorを含むjarに対する依存関係を設定する。QueryDslは本体機能へのAPI(querydsl-jpa.jar など)とは別に、Annotation処理のjarが切り出されている(querydsl-apt.jar)。querydsl-apt.jarは、実行時には不要であるため、独自にdependency condfigurationを設定した。(下記processor)

 configurations {
      processor {
          description: "classpath for annotation processors"
      }
  }
  • dependenciesクロージャで、processorquerydsl-apt.jar を指定する
 dependencies {
      compile "org.eclipse.persistence:javax.persistence:2.0.0"
      compile "org.eclipse.persistence:eclipselink:2.4.0"
      compile "com.mysema.querydsl:querydsl-jpa:2.7.2"
      compile "org.slf4j:slf4j-log4j12:1.6.6"

      processor "com.mysema.querydsl:querydsl-apt:2.7.2"
  }

antのjavac呼出タスク定義

  • Annotation Processingの出力先は、build/processorGen/srcとした。今回は拡張プロパティext.destdirに設定しておく。

task execProcessor {
      ext.destdir = new File(buildDir, "processorGen/src")
      // ...
  }
  • buildディレクトリ配下としたのは、cleanタスクで消してくれるため。例えばモデルクラスの名前を変更すると旧名のメタクラスが残ったままになってしまうなど、cleanできたほうが都合がよい。

  • もちろん毎回消して再生成もよいのだけど、今回はUP-TO-DATEを仕掛けてビルドを効率化したかった。
  • UP-TO-DATEは下記のように inputsとoutputsにそれぞれファイルまたはディレクトリを設定することで、変更の有無(つまりAnnotation Processingタスクの実行が必要かどうか)をGradleが判定してくれるようになる。

 task execProcessor {
      ext.destdir = new File(buildDir, "processorGen/src")
      inputs.source(sourceSets.main.java)
      outputs.dir(ext.destdir)
      doLast{ /* ここにjavacを呼び出す処理 */ }
  }
  • doLastクロージャで、このタスクの実行処理を記述する。この例ではantjavacを呼び出してみる。

doLast {
      ext.destdir.mkdirs() // 出力先が事前に存在しないとエラーになるのを回避

      def primaryOptions = [
          includeAntRuntime: false,
          destdir: ext.destdir,
          classpath: configurations.compile.plus(configurations.processor).asPath,
      ]

      ant.javac(primaryOptions) {
         sourceSets.main.java.addToAntBuilder((Object)ant, 'src', FileCollection.AntType.MatchingTask)
         compilerarg(value: "-proc:only") 
         compilerarg(value: "-implicit:none")
         compilerarg(value: "-processor")
         compilerarg(value: "com.mysema.query.apt.jpa.JPAAnnotationProcessor")
      }
  }
  • 上記のant.javacはおおよそ下記のようなant記述と同じ意味

    <javac includeAntRuntime=false
           destdir="${ext.destdir}"
           classpathref="${compiler.plus(processor).asPath}">
      <src ...ここはaddToAntBuilder()がゴニョゴニョする  />
      <compilerarg value="-Xlint"/>
      <compilerarg value="-proc:only"/>
      <compilerarg value="-implicit:none/>
      <compilerarg value="-processor/>
      <compilerarg value="com.mysema.query.apt.jpa.JPAAnnotationProcessor/>
    </javac>

compileJavaの設定

  • これで execProcessorを実行すればQueryDslによってメタクラスがbuild/processorGen/srcに生成される。だがこのソースが compileの対象になっていないのでこのままではコンパイルされない。
  • ここで src/main/javaディレクトリにコピーするという手もあるが、UP-TO-DATE判定を考えると好ましくない。また、Checkstyleといった静的解析ツールが処理する対象ディレクトリから自動生成されたコードを分離したいということもあるかもしれない
  • ということで、compileJavaの対象ソースディレクトリとして execProcessorの出力先ディレクトリを追加する。
  • また、compileJavaの依存タスクとして execProcessorを設定する。

compileJava {
      dependsOn execProcessor
      source execProcessor.ext.destdir
 }

これでcompileJavaを実行するとexecProcessorが先に実行される。

$ gradle compileJava
:execProcessor
[ant:javac] 注意:Running JPAAnnotationProcessor
[ant:javac] 注意:Serializing Entity types
[ant:javac] 注意:Generating .... for [...]
[ant:javac] 注意:Running JPAAnnotationProcessor
[ant:javac] 注意:Running JPAAnnotationProcessor
:compileJava

BUILD SUCCESSFUL

また、変更がなければ UP-TO-DATEと判定され、実行されない。

$ gradle compileJava
:execProcessor UP-TO-DATE
:compileJava UP-TO-DATE

BUILD SUCCESSFUL

スクラムマスターとサッカー監督の仕事について

先日受講したScrumの研修で、スクラムマスターはサーバント・リーダシップが求められる仕事と教わり、ふとサッカー女子日本代表(いわゆるなでしこジャパン)監督の佐々木則夫氏を連想した。
昨日のロンドン五輪サッカー決勝では惜しくもアメリカに敗れたものの銀メダルという好成績、ワールドカップでは優勝に導き FIFAの最優秀監督賞を獲得した名将である。

佐々木監督の著作「なでしこ力 さあ、一緒に世界一になろう!」(人に貸したので手元にない)やその他メディアの記事(ネタ元がみつからないw)に書いてあったという記憶を頼りに挙げてみる

  • 横並びの視点:監督と選手の間に上下関係を作らず、同じ目線でフレンドリーに接する。選手からふざけて「ノリオ」と呼ばれたりすることもあるらしい。しかし選手にナメられるわけではなく尊敬されるほどの実力(分析力、指導力)があるということ。著書を読んでも、とても選手やチームメンバに対する気配りが伺える
  • コーチング:試合前後の分析など、佐々木監督は選手に「課題」を与えるが、「答え」は教えないという。選手がビデオを分析して自分たちで答えを出す。監督は選手たちの答えに「よし、わかった」と承認する。
    • サッカーもソフトウェア開発も試合やプロジェクトが終わるまでは(もしくは終わっても)正解は誰も分からない。監督や誰かから答えを教わって(指示されて)プレーしても、サッカーもソフトウェア開発も開始前の計画の通りに進むなんてことはないし、とりわけサッカーにおいてはタイムアウトをとって監督の指示を聞くこともできないから、自分たちの判断でプレーしなくてはならない。そういう意味で、佐々木監督の構築するチームは、サッカーをプレーするための究極の自己組織化されたチームだ。
  • 「なでしこ力」にはビジネス書かよ?という小見出しも。
    • 適材適所で人の強みを活かす
    • トライ&エラー、まずは、やってみよう
    • 諦めなければ、夢はかなう
    • 肩書は部下を守るためにある
  • 社会人サッカー部の監督時代はあまり好成績ではなかった。
    • その理由はわからないけれども、自己組織化されたチームというのは選手にも相当のスキルを求められるだろうし、指示をそつなくこなすのが得意だというタイプのメンバだっているだろう。佐々木監督のメソッドはおそらくどんなチームにも万能な方法ではないし、日本の女子のトップ選手たちのあつまりである、なでしこジャパンだからこそ成立したのかもしれない。
    • ソフトウェア開発で世界一を目指すチームを構築しようと考えている人はほとんどいないと思うが、とはいえ、真に効率的で強いチームは独裁者による指示型ではないということを佐々木監督は証明してくれたと思う。

これが書かれたのはワールドカップ前。「さあ、一緒に世界一になろう」という本を出版して本当になっちゃったのだからもう驚きである。続編も出てるのでこんど読んでみるつもり。

[Gradle] http経由でファイルをダウンロードするスクリプト

WordPressがgist埋め込み対応したということで、試してみたかっただけです。

 


import java.io.*
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.EncoderRegistry
import static groovyx.net.http.Method.*
import static groovyx.net.http.ContentType.*
buildscript {
repositories {
mavenCentral()
mavenRepo url: "http://repository.codehaus.org&quot;
}
dependencies {
classpath 'org.codehaus.groovy.modules.http-builder:http-builder:0.5.2'
}
}
task downloadJslibs << {
def http = new HTTPBuilder('http://ajax.aspnetcdn.com/ajax/&#39;)
http.handler.failure = { resp ->
println "Unexpected failure: ${resp.statusLine}"
}
// proxy settings
def (host, port) = [System.properties.'http.proxyHost', System.properties.'http.proxyPort']
if(host) http.setProxy(host, port as int, "http")
def target = 'src/main/webapp/js/libs'
def contents = [
"jQuery/jquery-1.7.2.min.js": "jquery.js",
"jqueryui/1.8.22/jquery-ui.min.js": "jquery-ui.js",
"jquery.validate/1.9/jquery.validate.min.js": "jquery.validate.js",
]
def dest = mkdir(target)
contents.each() {
http.request(GET, TEXT) { req ->
uri.path= it.key
response.success = { resp, reader ->
println "$resp.statusLine saving downloaded file[$it.value] …"
new File(dest, it.value).setText(reader.text, "UTF-8")
}
}
}
}

view raw

build.gradle

hosted with ❤ by GitHub

Scrumのプラクティスっぽくサッカーを説明する

自分、アジャイルは理論派な方です!
(実践がほとんど伴っていないの意)

昨日、Scrumのセミナーを受講したので何か書こうと思ったのだけど、五輪も始まるし、Scrumのプラクティスっぽくサッカーを説明するという思考実験をしてみることにした。自分の中では両者はかなり類似していると思うので。

サッカーというのは、足という比較的ニブイ部位でイレギュラーバウンドしうるグラウンド上のボールをコントロールするという、不確実性てんこ盛りの競技である。しかも自分たちを打ち負かそうとする相手もいて、常に自分たちの裏をかこうと我々が予測もしないようなプレーをしかけてくる。ソフトウェアの開発と同様に、予測不可能な状況の変化の頻繁な発生に対して、チーム全員で対処する。時にはリスク覚悟でのチャレンジも勝利のためには必要な場合もあるという、ソフトウェア開発を90分に凝縮したようなスポーツだと思う。(ソフトウェア開発でのチャレンジって何だろうか。例えばチームが初めて使う技術で機能を実装するとかもそうだし、そもそもプロジェクトというのは既にチャレンジだし。Scrumを導入するというのもそうかもしれない。リスクやその対価として得る効果の大小は様々だけど、開発にはいろんなチャレンジが含まれてると思う)

Scrumチームについて

自己組織化

サッカーは試合が開始したら、監督の指示を待ってから選手がプレーをするようなスポーツではない。刻一刻と変化する状況に迅速に対処するには、誰かの指示を待っていては遅すぎる。ピッチで起きた問題を一番最初に知るのは、いつでもそこに居る選手である。だから選手は目の前の問題に対し、自分で考え自分で対処する。
チームは選手たちの得手不得手をお互いにカバーしあうことになる。誰かが相手のディフェンスを打開できなかったら、パス交換したり、まわりの選手がスペースに走りこんだりして「チームで」対処する。

役割はあるが、水平で対等

サッカーにおいては「スクラムマスター」のような役割は「監督」や「コーチ」に近く、「選手」は「開発者」にあてはまるかもしれない。
選手の中にもFW、MFのようなポジションや、わかりやすく言えば「司令塔」のようなロール(役割)があり、各選手は自分の役割を担いゲームに臨む。
ロールはあくまでロールであり、司令塔が一番えらいとか、GKはえらくないとか(またはその逆とか)はない。あくまで対等である。

責任をもつ

チームですることにチームが責任を持つ。サッカーは、試合に負ければチーム全員が敗者である。「自分はGKではないので失点したのは自分のせいではない。自分は敗者ではない」などと言っても仕方がないのであり、負けたのは「自分たちのチーム」である。
もうひとつ、Scrumにはいちいち書いていないと思うが、チームのメンバー個人にも、自分の役割をはたす責任はある。たぶん、これは欧米ではあたりまえだから書いていないのではないかと思うが、一昔前の日本人選手は(いや今でもたまに)、ゴール前でGKと1対1の状況というチャンスなのに横パスに「逃げる」というプレーが頻繁に見られた。
日本人は命令型のシステムで、上司や先生の指示に従うことで、つまり「言われたとおりにすること」によって、自分に責任がなく指示者が責任を負うということに慣れすぎているせいで、自己組織化されたチームでの役割を担うことに対し、それによって負う責任を重く感じてしまい、それから咄嗟に逃げようとしてしまった結果ではないかという分析をしている人もいる。他にも、失敗に対する寛容さだとかいろいろな要素はあるのだろうが、いずれにしろ各メンバーが自身の役割をまっとうしなければ、チームが機能するわけがない。

機能横断的(クロスファンクショナル)

一昔前のサッカーは、ソフトウェア開発もかつてはそうだったように、FWは攻撃専門、DFは守備専門といったスペシャリストによる完全分業が最も効率よい戦略とされていた。
しかし 1974年のワールドカップでオランダ代表が用いたトータルフットボールと呼ばれる、ポジションが流動的で全員攻撃・全員守備をする戦略がサッカー界に大きな影響を与えた。この戦術はチーム全員が複数のポジションの役割を担うことができ、チーム全体を掌握して自身がどのようにプレーすべきかという監督のような視点を持っていることが求められるため、戦術として理想ではあるが実現が非常に難しいものである。
現代のサッカー戦術にも大きく影響を与えている。例えば現代サッカーのFWは、相手にボールを奪われたときの一番最初の守備者でなくてはならない。相手DFが持つボールを、別のFWや攻撃的MFと協調して追い立てることを求められる。(スタミナを犠牲に、相手ゴールに近い位置でボールを奪うためのチャレンジをする)
日本サッカーも数年前までは、中央の攻撃的MFのポジション(トップ下などと呼ばれたりもする)の選手を「司令塔」と呼びゲームコントロールの役割を担っていたが、そのうち守備的MF(ボランチとも呼ばれたりする)がゲームを組み立てる役割を持つようになり(ボランチとはポルトガル語で「ハンドル(舵)」の意)、いまやセンターバックのDFの選手も、相手FWが追い立てるのをいなすことができる足元のテクニックが求められている。GKにも足元が求められるとさえ言う監督もいる。
ソフトウェア開発も、完全分業からクロスファンクショナルに移り変わっているのは、ハードルは高いものの、チームの戦略として最も効率が良く理想的であるからだと思う。

ところで、トータルフットボールのような、全員が連携して動くサッカーを「スペクタクル」とか「美しい」サッカーと表現されたりする。美しいサッカーはある程度のリスクを負って、それを選手の高いスキルによって低減し、高いレベルで効率よくプレーする。
それとは逆に、8~9人で守りを固めて、ボールを奪ったらロングボールを蹴って前線に残った1人に攻撃させるようなサッカーもある。「実践的」サッカーなどといわれ、リスクを最小限にし、勝つためというより負けないサッカーである。日本の高校サッカーのようなトーナメント方式だと、結構な割合で「実践的な」サッカーをするチームが上位に来る。もちろんどちらか一方が絶対的に優れているというわけではないが、顧客(オーナーやサポーター)が求めているのが負けないことなのかチャレンジなのか、あるいは美しさなのかということも大事な要素である。

一人の選手が複数の役割をこなすメリットは、このようなものがあるのではないかと思う。
ある選手がケガなどで試合に出られないときに、代わりをする選手がその役割を担うことができること。
ソフトウェア開発でも欠勤や研修で不在となるメンバーの代わりができる程度のバッファは必要であるが、専業分業スタイルのバックアップメンバーを用意するとしたら、完全に倍の人数が必要になってしまう。まぁこれはお金で何とか解決できないこともないかもしれないが、それとは別に、試合中の戦術変更を選手交代なしに行うことができるというメリットもある。(サッカーでは、選手交代は3人までというルールの試合が多い)
もうひとつ思うのは、Scrumの説明としてはどこにも書いてないかもしれないが、メンバーが固定であると、ぬるま湯というか現状肯定し更なるステップアップをしなくなってしまうリスクがあるので、それを回避する効果もあるのではないかと思う。ある人が専業的に1つの役割を担っていたりすると、もうこれ以上改善する余地がないと思い込んでしまってそのままになってしまうことはありうる。そんなときにメンバーを流動的にすると、まったく別の視点や方法から改善の余地が見えてくることもあるだろうと。

とりあえずScrumチームになぞらえてサッカーのチームについて語ってみた。中にはScrumのプラクティスの用語ではないものを使っているかもしれない。セミナー資料ベースで考えたので(汗 という逃げ。。
他のプラクティスも何か通ずるものがあるかもしれないので、思いついたら書くかもしれない。

最後に、サッカーの戦術もトレンドがあり、また選手たちのフィジカルが向上したり、シューズなどの道具の進化もあるだろうしトレーニング手法の進化などによって、戦術自体も可能性が広がり進化を続けている。ソフトウェア開発も同じように進化しつづけるだろう。
10年前のJリーグと今のJリーグとでまったく違うサッカーに進化しているように、数年後の日本のソフトウェア開発もスペクタクルで美しいものに進化していることを望むし、微力でもその助力となりたいと思う。

[gradle] TaskとAction

自分がGradleでハマッたポイントを晒してみる

task copyTaskA(type: Copy) {
  from 'src/main/webapp'
  into 'build/explodedWar'
}

task copyTaskB {
  copy {
    from 'src/main/webapp'
    into 'build/explodedWar'
  }
}

上のcopyTaskAとcopyTaskBは同じだと思って何気なく書いていたのだが、しばらくしてcopyTaskBのコピーが、依存タスクに関係なく、いつでも実行されてしまっていることに気づいた。

結論をいうと、copyTaskAと同等のタスクにするには << が必要だった。

task copyTaskA(type: Copy) {
  from 'src/main/webapp'
  into 'build/explodedWar'
}

task copyTaskB << {
  copy {
    from 'src/main/webapp'
    into 'build/explodedWar'
  }
}

こたえはここに書いていた。
Example 48.1. Single project build
つまりこういうことらしい

task configured {
  // ここは、タスク自体のプロパティを設定するところ
  // gradleの実行時にすべてのタスクで評価が行われる
}

task actionAdded << {
  // ここは、actionAddedタスクが直接的に呼び出されたり、依存元タスクが呼びされれたりすると実行される
}

では、taskに << {}するとは何なのか。ここでGradle DSLのドメインモデルを。


Gradleでは、Project、Task、Actionのような階層になっていて、Taskは Actionオブジェクトのシーケンスを持ってる。<<演算子は、そのシーケンスにActionを追加する。また、Taskの doFirstとdoLastメソッドでActionを追加することも可能。たとえばcompileの前にファイルコピーをしたかったらこのように書く。

compile.doFirst {
  copy {
    from 'otherdir/othersrc'
    into 'src/main/java'
  }
}

ちなみにここのcopyは Projectクラスのメソッドであり CopyTask (一番最初にcopyTaskA(type: Copy)と書いたもの)とはまったく関係ない。Projectクラスのメソッドは build.gradle内のどこからでも呼べることになっている(たしか。原典みつからず)というルールで実現されている。task myTask {…} の taskも同じ。

話はそれるが、~の前にしたいコピーをタスクにして依存関係を持たせることもできる。compileタスクが実行される前にmyCopyが実行される点は同じだが、myCopy単独で実行もできる(Taskなので。)

task myCopy << {
  copy {
    from 'src/main/webapp'
    into 'build/explodedWar'
  }
}
compile.dependsOn(myCopy)

参考までに