似非プログラマのうんちく

「似非プログラマの覚え書き」出張版

Apache Maven を使ってみよう(その 3)

Mavenプラグインについて

Mavenプラグインは主に以下のサイトで用意されている。
Maven – Available Plugins
Mojo – MojoHaus Maven Plugins Project

Exec Maven Plugin

前回の課題になっていた、Maven のビルドの実行の際に main を実行するためには、Mojo で用意されている Exec Maven Plugin を利用する。

pom.xml を修正する。

<project
  xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>jp.mydns.akanekodou</groupId>
  <artifactId>MavenSample</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>

  <name>MavenSample</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.4.0</version>
        <configuration>
          <mainClass>jp.mydns.akanekodou.App</mainClass>
        </configuration>
        <executions>
          <execution>
            <phase>test</phase>
            <goals>
              <goal>java</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

build 要素が新たに追加され、その直下に plugins 要素がある。Mavenプラグインにはビルドプラグインとレポーティングプラグインがあり、Exec Maven Plugin はビルドプラグインなので build 要素に追加することになる。

今回は mvn test を実行したら自動的に mvn test exec:java が実行されるように設定している。

mvn test を実行すると…

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running jp.mydns.akanekodou.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.148 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] 
[INFO] --- exec-maven-plugin:1.4.0:java (default) @ MavenSample ---
Hello World!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.490 s
[INFO] Finished at: 2015-08-27T20:57:56+09:00
[INFO] Final Memory: 11M/212M
[INFO] ------------------------------------------------------------------------

確かに実行されている。

Apache Maven を使ってみよう(その 2)

Maven のビルドライフサイクル

Maven のビルドライフサイクルには多数のゴールが設定されている。ちなみにデフォルトのライフサイクルには何と

validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy

こんなにゴールが設定されている。

しかし、実際にはこれを全部使うことはない。以下、主だったものを説明する。

続きを読む

Apache Maven を使ってみよう(その 1)

当ブログではこれまで Apache Maven (以下、Maven) の話題は極力避けてきたが、昨今の開発事情を鑑みるに、最早 Maven なしでは開発がままならない状況になりつつある。Spring MVC では標準のビルドツールとして採用されるなど、Maven は避けては通れないものになっている。

Maven はなぜ便利なのか ?

ビルドライフサイクルの自動化

IDE を使っているとあまりピンと来ないかも知れないが、たくさんの Javaソースコードを一つ一つ手でコンパイルするのは大変な作業である。Maven でプロジェクトを管理しておけば、コマンド一つでコンパイルを含むビルドライフサイクルを全て自動化できる。

依存ライブラリの管理ができる

プロジェクトが依存するライブラリを一つ一つ探してくるのは大変な作業。しかし Maven なら、設定ファイルである pom.xml に記述しておけば Mavenリポジトリから勝手にダウンロードしてくれる。さらに、依存するライブラリが依存する別のライブラリがあれば、ほとんどのケースでそれらも勝手にダウンロードしてくれる。

プラグインによる拡張性

Maven には様々なプラグインがあり、それらを組み込むことで Maven をより使いやすいものに出来る。場合によっては自分でプラグインを作ることも出来る。

Scala や Groovy も O.K.

Maven さえあれば、Java VM 上で動く Scala や Groovy と言った言語での開発も可能。しかも Scala や Groovy を別途インストールする必要がない。

こういった理由により、Maven の使い方を覚えることは非常に有効であり、開発の手間を大いに省くことが可能になる。そこで今回からは Maven の基本的な使い方を連載していこうと思う。

続きを読む

Ruby で FizzBuzz を満喫する

Scala にだいぶSAN値を削られたのでここいらで Ruby に日和ろう(苦笑)。

その 1 : Object#tap を利用する

to_fizzbuzz = -> n {
  "".tap do |_|
    _ << "Fizz" if n % 3 == 0
    _ << "Buzz" if n % 5 == 0
    break n if _.empty?
  end
}

puts 1.upto(100).map(&to_fizzbuzz)

RubyObject#tap はブロック内で自分自身に対して行われた破壊的変更が保証される。break が発動するとそれらの変更を破棄して強制的に別の値を返すことが出来る。発動しなければブロック内で行われた破壊的変更を適用した自身が返ることになる。

さくっと lambda 奴を使っておくと Enumerable#mapProc オブジェクトを渡す Ruby らしい書き方で処理が記述できる。

その 2 : Hash を利用する

Scala 編で Map を使ったやつの元ネタ。

Applicators = {3 => :Fizz, 5 => :Buzz}

to_fizzbuzz = -> n {
  fb = Applicators.select{|_| n % _ == 0}.values.join
  fb.empty? ? n : fb
}

puts 1.upto(100).map(&to_fizzbuzz)

やってることはほぼ一緒。メソッド名が違うだけ。

その 3 : Enumerable#zip を利用する

fizz = [nil] * 2 << :Fizz
buzz = [nil] * 4 << :Buzz

1.upto(100).zip(fizz.cycle, buzz.cycle) do |n, *f|
  puts f.any? ? f.join : n
end

ネットで見つけてきた。nilany の使い方が Ruby っぽくてお気に入りである。

続きを読む

Scala でとことん FizzBuzz する(その 4)

最初にお詫び。前回の記事にかなり大幅な修正を加えています。再度確認をしていただけるとありがたいです。

追記 : 今回作ったソースファイル群(+ テストコード)を GitHub で公開しました。
akaneko3/FizzBuzzScala · GitHub

続きを読む

Scala でとことん FizzBuzz する(その 3)

さぁ、改造を続けよう。

FizzBuzz アルゴリズム再考

ちょっとひねって、次のような写像を考える。

何も書いていないところは空文字列を対応させていると考える。これを利用して、FizzBuzzアルゴリズムを少し変更する。

  1. 何らかの方法で "", "", "Fizz", "", "Buzz", "Fizz", "", "", "Fizz", "Buzz", "", "Fizz", "", "", "FizzBuzz", ... と繰り返される列を用意する。
  2. 1 から順に上記の列と対応させていく(zip)
  3. 上記で得られた列を順に処理していくとき、「数字と空文字列」の組み合わせのときは数字を、「数字と空でない文字列」の組み合わせのときは文字列を返すようにする。

これを Scalaトレイトを利用して抽象クラスとしてあらかじめ作っておく。

package jp.mydns.akanekodou.scala.fizzbuzz

abstract class FizzBuzz {
  protected val fb : Stream[String]

  def fizzbuzz : Unit = {
    1 to 100 zip fb map {
      case (n, "") => n
      case (_, s) => s
    } foreach println
  }
}

Java のインターフェースと違い、Scala のトレイトにはこうした共通処理をあらかじめ実装しておくことが出来る。今回、ついでなので表示するところまでまとめて実装してみた。

2015/04/12 追記 : 今回のケースではトレイトを使う必要はありませんでした。お詫びの上、通常の抽象クラスに訂正させていただきます。

もう一つ、Scala の機能である「暗黙引数」を利用している。一見するとメソッドの引数のデフォルト値をあらかじめ与えるのと似ているが、あちらはあらかじめ引数を初期化しておかないとダメなのに対し、こちらはメソッド呼び出し時までに暗黙引数を初期化・確定させておけば良い。

Java の抽象クラスは「抽象メソッドが含まれるクラス」であるが、Scala の場合は抽象メソッドに加えて上記のような抽象フィールドを含むクラスも抽象クラスとして定義しなければならない。

2015/04/12 追記 2 : MainFizzBuzz 系クラスを継承させる方法が何となく行儀が悪く見えたので止めました。

その他のファイルも適宜書き換えていこう。

package jp.mydns.akanekodou.scala.fizzbuzz

class FirstFizzBuzz extends FizzBuzz {
  def toFizzBuzz(n : Int) : String = {
    if (n % 3 == 0) {
      if (n % 5 == 0)
        "FizzBuzz"
      else
        "Fizz"
    } else if (n % 5 == 0) {
      "Buzz"
    } else {
      ""
    }
  }

  val fb = Stream.from(1).map(toFizzBuzz)
}

toFizzBuzz は最早 String 型しか返さないことが明白になった。

package jp.mydns.akanekodou.scala

import jp.mydns.akanekodou.scala.fizzbuzz._

object Main extends App {
  (new FirstFizzBuzz).fizzbuzz
}

Main.scala がだいぶすっきりした。

いよいよ本格的に改造していくぞ !

続きを読む

Scala でとことん FizzBuzz する(その 2)

前回のプログラムは無事動いたかな ? では改造を始める。でもその前に…。

SBT で作ったプロジェクトを Scala IDE for Eclipse で扱えるようにする

前回までの手順で、プロジェクト直下に project フォルダが出来ていると思う。そこに plugins.sbt というファイルを以下の内容で作成する。

addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.5.0")

そうしたらプロジェクト直下で

> sbt eclipse

を実行する。これにより Eclipse 用の設定ファイルなどが作られ、Scala IDE for Eclipse でプロジェクトをインポートして扱うことが出来る。コーディング作業は IDE を使う方が楽なのでやっておくと良い。なお、SBT でライブラリの依存関係を変更したときは再度上記コマンドを実行しないと Eclipse 側に反映されないので注意。

続きを読む