Ruby はじめました

お仕事に刺激がないので、なんとなく Ruby を勉強し始めました。

教科書はこちら。
選定理由は本屋にあったもので、初心者っぽくないもの。

しばらく読書を続けていましたが、飽きてきたので写経しながら読み進めています。

Ruby 触ってみての感想

これまで Ruby 触ったことがないわけではないですが、
きちんと向き合ったのは初めて。

・Groovy と似てる。(Grooby が Ruby に似ている、が正しいけれど)
Java とは色々な意味で違うのでおもしろい。
・まだまだ良さはわからない。いいんだろうな…たぶんくらい。

おまけ:ひさびさのブログ更新

最後にブログを更新したのが200日前のようです。
半年以上放置していたわけですが、1日あたり40PVくらいありました。
放置しているのに見に来ていただけるのはありがたいですね。

働き方を見つめなおす - 『「やりがいのある仕事」という幻想 』

特に仕事の悩みを抱えているわけでもないですが、本屋で目に留まったので読んでみました。
著者の森博嗣さんは小説家として有名ですよね。


仕事についての考えが変わるかも

働き方、仕事というものに対して、世間一般的な視点ではない、異なる視点で分析しています。

仕事とは金を儲ける行為であると定義した上で、
仕事に対する既成概念をどんどん否定していくのが痛快でした。

「仕事つらいだろうけど、我慢して頑張れよ」
なんてことは一言も書いてないです。

仕事に対する捉え方が自分と似ていて、自分の考え方を整理するのに非常に役立ちました。
うまく言葉に現されているので今後どしどしと引用させていただこうと思います。

仕事におけるやりがいの捉え方

仕事をしている中でやりがいを感じる、楽しいと
思えるのはいつなのかを考えてみます。

たとえば最も仕事に熱中しているときというのは、
新たな発見があって好奇心を刺激されるときだったりします。

そういうときは会社に貢献しているというよりも、
自分の成長に喜びを見いだしているわけで…
雑なクオリティで終わっても文句言われないところを深追いしてしまう感じです。

「ここまでやらなくても」とか言われますが、「資料作りながら、頭の中身整理できてよかった」
というようなことを思ってたりします。*1
(作りすぎのムダについての議論はここでは置いておいて)

あとはこんなことして金もらえるのはお得だなあということもありますね。
給料をもらえる上に、自分の成長のために会社の資産を使っているわけで。

そういうときに深夜まで会社に残っていても苦ではないです。
もはや仕事ではないです。仕事に楽しみを見いだした、やりがいを感じている
という捉え方もできますが、「会社で自分が楽しいことしている」と捉えた方がすっきりします。

この本では後者の捉え方で話が進んでいきます。
そういう捉え方でいいんだということに自信がつきました。

*1:あとがきの中の「僕は何のためにこれを書いたか」で同じようなことが書かれていてビックリしました。

プログラミング言語の理解を深める - 『コーディングを支える技術』

今回の読書感想文は、たまたま本屋さんで手に取って
衝動的にそのまま買ってしまった『コーディング支える技術』です。


言語の学び方

冒頭で言語の学び方は3つあるとしています。

・比較から学ぶ
・歴史から学ぶ
・作ることで学ぶ

そのうち、比較から学ぶ・歴史から学ぶのスタンスで
プログラミング言語の文法のなぜについて解説されています。

比較から学ぶ、あいまいな理解

Java は文法を理解しているのですが、実は JavaScript は文法をよく理解していなかったりします。

Java の文法をベースに考えたり、よくわからない所は適当に実装してうまくいったら
OK みたいな感じになります。
たとえば、JavaScript の undefined はあいまいな感じでした。

この言語ではこうだけど、違う言語では同じものでも違う扱いになる、違う結果になる事例が
たくさん紹介されています。

主たる言語以外の言語の文法について、あいまいな点がいくらか整理できたのはよかったです。

歴史から学ぶ、文法のなぜ

文法って、こういうもんだと決めつけて理解して現在に至っているものが実は多いです。

この本では、よくある文法をゼロから成り立ちを勉強することができます。
なぜこの言語では例外処理はこういう文法なのか、そういったようなものです。

文法が作られた理由や経緯、メカニズムが紹介されていますが、いつも使っているだけに
興味深い内容が多いです。
文法が作られた理由を知ると、これほど理解が進むのかと驚かされました。

さいごに

8章の「型」についての解説は、Amazon のレビューにもあったのですが
非常にわかりやすく、納得感がありました。読む価値があると思います。

浮動小数点数がやっと理解できました。
情報処理試験で次からはそれ関連の問題が出ても太刀打ちできそうです。

文字コードと向き合えるように -『プログラマのための文字コード入門』

今週のお題「2014年プライベートでやりたいこと」に乗っかって、ブログをひさびさに。

今年は本読んだらブログにアウトプットしようと思ってます。
まず一冊目、『プログラマのための文字コード入門』です。


文字化けと私

長らくシステム開発のお仕事をやっていますが、文字化けが大嫌いでした。
生理的に受けつけない、一番嫌いなレベルです。

理由はメカニズムをよく理解していないから。
そして、理解しようという気がないからです。

とはいえ、文字化けや文字コードに対して見解を求められることも増えてきており、
現在のプロジェクトでも質問攻めにあい、逃げ腰で耳塞いでいると後々火が吹きそうな予感。

意を決して文字化けと向き合おうとしました。

そのとき手にとったのがこの本です。

嫌いだったからこそ…

この本の存在自体は前から知っていました。読んで知識を充実したい思いもありました。
ですが、生理的に受けつけないのでパラパラめくって見ないふりでした。

そういう人間でしたが、読んでみるとなかなかに興味深い内容でした。

苦手分野だったため時間もかかり、睡魔にも度々襲われましたが、
読み進めるたびに発見があり充実感を得ました。

苦手意識を長年蓄積していただけあって、問題意識はたっぷり持っていました。
この本を読むための目的が人一倍あったことになります。

「文字化けのこの部分がよくわからんっ」というようなクエスチョンは明確にあり、
回答を探し求めるように読みふけました。

・JIS第三水準、第四水準ってなに?
Shift_JIS、MS932、CP932、Windows-31J って何使えばいいの?
機種依存文字ってなに?
草なぎ剛の「なぎ」って、扱いなんなの?
・波ダッシュ(〜)はDBに入れるとなんで文字化けするんだ?
Unicode は一体、1文字何バイトなのだ?
・LF、CRLF とか改行コードの違いって意識せなあかんのか?

こんな疑問たちを長年蓄積していて、断片的にググった内容で
わけもわからず都度乗り切っていたわけですが…

今となっては、胸張って回答やら仕組みを言えてしまうというスゴさ。

この本に感謝です

文字化けはまだまだ嫌いですが、少し嫌いくらいまでになりました。
おそらく文字化けについて、人並みかそれ以上はしゃべれる自信がつきました。

本を読んで、こんなにスッキリになったのは久しぶりです。

ふつうのWebアプリにGradleをしこむ

個人的にテストコードを書いたり、Gradle で自動化するのを実践しているのですが、
仕事に活かせているのは小規模で自分の裁量が大きいプロジェクトに限られています。

大規模なプロジェクトになると色々と抵抗勢力が多くて、色々と説得するのが億劫なので
こっそり Gradle を仕込んで Jenkins 動かそうと今試みています。

個人的にはコソコソ動いてておもしろいので、成果をメモしていきます。

"ふつう" な前提条件

Gradle を仕込むのは「ふつうの Eclipse プロジェクト」です。
ここで言う「ふつう」とは…

Maven ディレクトリ構成ではない

src/main/java, src/main/resource, src/main/webapp といったディレクトリ構成ではなく、
src の下に java ファイルがあったり、WebContent ディレクトリの下に WEB-INF や JSP があったりです。
Eclipse がプロジェクト新規作成時に勝手に作ってくれるディレクトリ構成ですね。

◯みんなのPCには Maven も Gradle も入ってない

そんなビルドツールなんて知りません。Eclipse の付属で付いている Ant のちょっとしたビルドが
動いているかもしれません。でも、そんなの意識したことがありません。

jar ファイルは WebContent/WEB-INF/lib にちゃんとコミットして置く必要があります。
ビルドするたびにリポジトリから最新のライブラリを取得するなんてよくわからないです。
それに、プロキシが邪魔して Gradle のプロキシ設定しないと、社外にはアクセスできないです。

◯自動化するからといってやり方が変わるのは嫌だ

Maven でビルド動かさないと jar ファイルが見つからないとか、そういうのはいけません。
Subversion からソースコードを取得したらそのまま使えるのが大事です。
build.gradle というよくわからないファイルがコミットされてるぞ?くらいで留めないとダメです。

こっそり仕込むこと

主に Gradle と Jenkins を使って、色々と自動化を仕込んでいきます。

1.War ファイルを作る  ←今ココ
2.ちょっとずつ作っていく JUnit テストコードでテストする
3.テスト環境に War ファイルをデプロイする
4.テスト環境でスモークテストを実行する

とりあえず build.gradle ファイル

apply plugin: 'war'

repositories {
    mavenCentral()
}

dependencies {
    compile fileTree(dir: "WebContent/WEB-INF/lib", include: '*.jar')

    compile 'org.apache.tomcat:tomcat-servlet-api:7.0.42'
    compile 'org.apache.tomcat:tomcat-jsp-api:7.0.42'
}

project.webAppDirName = 'WebContent'

sourceSets {
    main {
        java {
            srcDir 'src'
        }
        resources {
            srcDir 'src'
        }
    }
}

war {
    exclude 'WEB-INF/lib/**'
    exclude 'WEB-INF/classes/**'
}

def defaultEncoding = 'UTF-8'
compileJava {
    options.encoding = defaultEncoding
}

以下、順を追って設定内容を説明していきます。

お決まりの冒頭

apply plugin: 'war'

repositories {
    mavenCentral()
}

Java の Web アプリケーションなので、War プラグインを設定します。
あと、リポジトリMaven セントラルレポジトリを設定します。
ここまではお決まりです。

jar ファイルはすでにコミットされているものを使う

dependencies {
    compile fileTree(dir: "WebContent/WEB-INF/lib", include: '*.jar')

    compile 'org.apache.tomcat:tomcat-servlet-api:7.0.42'
    compile 'org.apache.tomcat:tomcat-jsp-api:7.0.42'
} 

普通は依存関係にある jar ファイルは次のような形式で書いてリポジトリから取得するのですが、

compile 'org.springframework:spring-web:3.2.1.RELEASE'

jar ファイルは WEB-INF/lib にコミットされているものを使わないといけないので、
そのディレクトリにある jar ファイルをコンパイル時に参照するように設定します。

例外的に Tomcat のランタイムの jar ファイルをコンパイル時に参照するように設定しています。
Eclipse プロジェクトではサーバランタイムを参照するように設定します。それに対応するものです。
これを設定しておかないと、Gradle でビルドするときに HttpServletRequest などの Java EE クラスが
存在しないということでコンパイルエラーになります。
Gradle で動かす時だけ Tomcat のランタイムをレポジトリから引っ張ってくることになります。

Maven ディレクトリ構成ではないので調整する

project.webAppDirName = 'WebContent'

sourceSets {
    main {
        java {
            srcDir 'src'
        }
        resources {
            srcDir 'src'
        }
    }
} 

Gradle や Maven のデフォルトのままだと、

 JSP や WEB-INF は… src/main/webapp ディレクトリ
 Java ファイルは… src/main/java ディレクトリ
 Java 以外のファイルは… src/main/resources ディレクトリ

に配置しないと動かないので、次のようにディレクトリ構成を変更しています。

 JSP や WEB-INF は… WebContent ディレクトリ
 Java ファイルは… src ディレクトリ
 Java 以外のファイルは… src ディレクトリ

本当はテストコードのディレクトリ構成も調整しないといけないのですが、
今はテストコードがないので調整していません。

War ファイルを作るときの不都合を回避する

war {
    exclude 'WEB-INF/lib/**'
    exclude 'WEB-INF/classes/**'
}

「gradle war」をたたくことで、Gradle が War ファイルを作ってくれるのですが、
ディレクトリ構成をいじったりしていることもあり、作成された War ファイルの中を見ると
同じファイルが重複して梱包されてしまいます。ファイルがサイズ膨大化します。
重複を回避するおまじないです。

エンコーディングを指定する

def defaultEncoding = 'UTF-8'
compileJava {
    options.encoding = defaultEncoding
}

ほとんどお決まりのような設定です。
こちらも本当はテストコードに対する指定も必要です。

こっそり War ファイルを作成できるようになる

色々と書きましたが、build.gradle を少し調整するだけで
Gradle をインストールした環境で「gradle war」とするだけで War ファイルが作れます。

自分のPCやテスト環境に Gradle を入れることとで、こっそりと簡単に実行できます。

問題点はテストコードがなく自動テストをしていないので、作った War が正しく動くかはわからないということです。それをやるためにはテストコードを書かないといけないのですが、それはハードル高いですね。

まずは War ファイルを作れるようになったということで。
Eclipse プロジェクトの右クリック→「エクスポート」→「War ファイル」からの脱却です。