一般的なShellで空白を含むPathをループしたい願望
まず、Shellって何かがわからないところから入るわけだけど、
いや、自分が打っているのが所謂sh
なのかbash
なのかzsh
なのかがわからないってことなんだけど、
まあ複数ファイルを順次処理したい時ってあるわけですね。
forを使ったループ
シンプルな例だと以下のように書くわけです。
for f in path/to/target/*.txt do echo "file is: $f" done
このディレクトリーにa.txt
, b.txt
, c.txt
があれば、以下のように表示されるでしょう。
file is: path/to/target/a.txt file is: path/to/target/b.txt file is: path/to/target/c.txt
スペース(など)が含まれたパス
ところが、スペースが含まれているようなディレクトリー名だと、これがうまく動かないのです。
ディレクトリー名をpath/to target with space/
だとしてみましょう。
ls "path/to target with space/"
a a.csv b c d.csv
こんな場合ですね。
同じようなループを実行すると、当然うまく行きません。
for f in path/to target with space/*.csv do echo "file is: $f" done
結果はこんな感じになったりしてしまいます。
file is: path/to file is: target file is: with file is: space/*.csv
解決方法1: IFS
組み込み変数を使用
どうにかスペース入のパスをループできないのかなーと検索した結果見つけたのが、
組み込み変数IFS
とfind
コマンドを組み合わせる方法です。
IFS
を変更すると、shellが扱う区切り文字を変更できるとこのことです。
まずfind
を実行すると、以下のような結果が取得できます。
> find "path/to target with space" -type f -name "*.csv" path/to target with space/a a.csv path/to target with space/b c d.csv
結果が改行されて出てくるので、IFS
に改行記号\n
を設定後ループするとうまくいくようです。
ただし、IFS
を元に戻せるように、退避してから実行した方が良いようです。
IFS_BACK="$IFS" IFS=$'\n' for f in `find "path/to target with space" -type f -name "*.csv"` do echo "file is: $f" done IFS="$IFS_BACK"
file is: path/to target with space/a a.csv file is: path/to target with space/b c d.csv
解決方法2: ""
でくくる
とりあえず上をコピペして使っていたのですが、 今日もっと簡単にできる方法を発見してしまったのでそちらに書き換えることにしました。
皆さんご存知のように、shellではダブルクォートに囲まれた部分は1つとみなしてくれるのです。
ただし、中にある*
は展開してくれません。
まず、ダメな例。
for f in "path/to target with space/*.csv" do echo "file is: $f" done
これの結果は以下のようになります。
file is: path/to target with space/*.csv
*
がそのままですね。
すごく単純すぎて気づかなかったのですが、
*
をダブルクォートの外に出してあげれば展開されるんですよね、これ。
for f in "path/to target with space/"*".csv" do echo "file is: $f" done
file is: path/to target with space/a a.csv file is: path/to target with space/b c d.csv
どこでダブルクォートを終わらせてもいいみたいなので、変数の部分だけくくるとかが現実的なのかなという感じです。
BASE_PATH="path/to target with space" for f in "$BASE_PATH"/*.csv do echo "file is: $f" done
結論
shell難しい。
自分のshell力の低さを痛感させられた。
自分用メモ #scala
アレ用のアレ。
implicit def fs2effectTask: fs2.util.Effect[scalaz.concurrent.Task] = { import scalaz.concurrent.Task import fs2.util.Effect new Effect[Task] { def fail[A](err: Throwable) = Task.fail(err) def attempt[A](t: Task[A]) = t.attempt.map(_.toEither) def pure[A](a: A) = Task.now(a) def bind[A,B](a: Task[A])(f: A => Task[B]): Task[B] = a flatMap f override def delay[A](a: => A) = Task.delay(a) def suspend[A](fa: => Task[A]) = Task.suspend(fa) override def toString = "fs2.util.Effect[scalaz.concurrent.Task]" } }
SQL99のWITH句について
MySQLしか触った事のない人にとっては全く知らない文法だというとこを最近知ったので。
WITH
句とは
WITH
句は、ネストされたテーブルに別名をつけて読みやすくするために使用する構文。
PostgreSQL
, Oracle
, MS SQL Server
などで使用可能。
MySQL
は(少なくとも少し前のバージョンでは)対応していない。
-- ネストされたテーブル SELECT * FROM ( SELECT user_id, SUM(payment) AS total_payment FROM payments GROUP BY user_id ) a WHERE a.total_payment > 3000
この例だとHAVING
すればいいとかはひとまず無視して、WITH
を使うとこんな感じ。
WITH a AS ( SELECT user_id, SUM(payment) AS total_payment FROM payments GROUP BY user_id ) SELECT * FROM a WHERE a.total_payment > 3000
通常の言語の変数宣言と同じ!!便利!!!
変数のように、適切な名前をつけるべき。a
とかb
とかf
とか。
複数の変数を使用する
WITH
句で複数のテーブルを取得する場合、,
で繋げる。
WITH a AS (SELECT ...), b AS (SELECT ...), c AS (SELECT ...) SELECT * FROM c
自分より上で宣言された別名は利用可能!!
WITH a AS ( SELECT user_id, MAX(log_date) AS log_date FROM some_log GROUP BY user_id ), b AS ( SELECT * FROM some_log s WHERE EXISTS( SELECT 0 FROM a WHERE a.user_id = s.user_id AND a.log_date = s.log_date ) ), ...
再帰
一部条件を満たせば、自分自身の中でも再帰的に参照が可能。
WITH a AS ( SELECT 0 AS index UNION SELECT index + 1 AS index FROM a WHERE index < 2 ) SELECT * FROM a
- PostgreSQLでは
WITH RECURSIVE a AS
としないと不可。他のDBは知らない。
つまり1番目の変数のみ再帰可能。
関数型の再帰と同様に、ループの終了条件書かないと無限ループして返ってこないので注意。
結果はこんな感じ。
index ===== 0 1 2 3
これを利用すれば「n月m日からo日までの毎日、0件なら0を取得する」なども簡単ですよね?
パフォーマンスについて
WITH
句で別名をつけた場合、1つの名前につき最大1回しか読み込まれないことが保証される。
また、ほとんどのDBMSではSQLを最後まで読み込んだうえで最適化するので、インデックススキャンで済むものは一時テーブルを作成しない。
なのでネストした表現と最低限同等、読み込み回数によってはWITHの方が圧倒的に効率化が可能。
でも、最後に信じるべきはオプティマイザーですね。過信ダメ、ゼッタイ。
あ、MySQLではCREATE TEMPORARY TABLE 〜 SELECT 〜を使おう。
こっちは自分でインデックス貼れるのでもっと早いよ!!!
AnsibleでDockerとかしたいのにdocker-pyに苦しめられた話
はい。タイトル通りです。
ansibleとはpythonで動いてるけどpython書かなくてもいい不思議な何かという認識。
で、ansibleからdockerコンテナー立ち上げるときのレシピがこちら。
--- - name: Run CentOS container docker: image: "centos:centos6" name: sample001 tty: yes net: host docker_api_version: 1.18
net=host
はネット設定はデフォルト不可だよというエラーメッセージ用、
docker_api_version=1.18
は本番で動いてるdockerのバージョン違うよ用です。
なのですが、これを実行してもdocker-py
が見つからないよ系エラーが出るのです。
ということでローカルでpip install docker-py
したりしてみたのですが、
これが一向に消えてなくならない。
virtualenvがダメなのかもとか悩んでいろいろググったり試したりした結果・・・
docker-pyは設定先の環境のデフォルトpythonに必要でした!!
はい。ローカルに入っていようが関係なかったのです。
よって、必要なのは設定先ホストでのpip install
。
これもansibleに書いてしまいます。
--- - name: Install docker-py become: yes become_method: sudo become_user: root pip: name: "docker-py" version: 1.7.1 state: present
ansibleの恒等性とかを考えると、state=latest
とどっちがいいのかわかりません。
sudoはたぶん必要。と信じている。
このためにはサーバーにもpipが入っていないといけないので、 それはサーバーのディストリビューションに合わせてって感じになるのかと。
私からは以上です。
GolangでShift_JIS(Windows31J)のファイルを読み込み
たどり着くまで時間がかかったのでメモ。
文字コードを意識しないファイルの読み込み
つまりはUTF-8のファイル。BOMはどうなんだろう?(試していない)
os.Openとbufio.NewReaderで行ごとに読み込める。
注意点: 読み込み完了時はerror
にio.EOFが入る。
package main import ( "bufio" "fmt" "io" "os" ) func main() { path := "/path/to/your/file" fp, err := os.Open(path) if err != nil { panic(err) } defer fp.Close() reader := bufio.NewReader(decoder.Reader(fp)) for { line, _, err := reader.ReadLine() if err == io.EOF { break } else if err != nil { panic(err) } fmt.Println(string(line)) } }
文字コードを考慮する。
とりあえずgolang decode
とかでググってみるとencodingパッケージが出てくる。
どうやらDecoder.ReaderでラップしたReaderが作れそう。
じゃあDecoderってどうやって作るの?と探したところ、japaneseパッケージにShiftJIS
を発見。
こいつがencoding.Encoding型なので、NewDecoder
メソッドを持っているらしい。
とりあえずjapanese
パッケージをゲット
go get golang.org/x/text/encoding/japanese
package main import ( "bufio" "fmt" "golang.org/x/text/encoding/japanese" "io" "os" ) func main() { path := "/path/to/your/file" fp, err := os.Open(path) if err != nil { panic(err) } defer fp.Close() decoder := japanese.ShiftJIS.NewDecoder() reader := bufio.NewReader(decoder.Reader(fp)) for { line, _, err := reader.ReadLine() if err == io.EOF { break } else if err != nil { panic(err) } fmt.Println(string(line)) } }
bufio.NewReader
に変換する前にデコードをはさめばOK
わかれば簡単。
ScalaでゆるふあにDB接続
この記事はScala Advent Calendar 2015 12日目です。
昨日は同じく私による今日から始めるScalaプログラミングでした。
前置き
私はアプリケーションにSQLを自分で書きたい派です。
参考: ScalaでSQLが書きたいんだ!!
なので積極的に自分で書けるライブラリーが好きです。
- DBに直接繋いで、取得結果や処理速度などを調整するクエリーを書く。
- 出来上がったクエリーを作成するためのScalaコードを書く。
こんな風に作業したいのです。
doobie or not DB
ということでdoobieです。
doobieによるシンプルなDBアクセスコードは以下のような感じです。
import doobie.imports._ case class User(id: String, password: String, email: Option[String]) object User { def byId(id: String): ConnectionIO[Option[User]] = sql"SELECT id, password, email FROM users WHERE id = ${id}".query[User].option }
呼び出す側はこちら
import doobie.imports._ import scalaz.effect.IO val xa = DriverManagerTransactor[IO]( "com.mysql.jdbc.Driver", "jdbc:mysql://example.com:3306/example", "user", "password" ) val a: ConnectionIO[Option[User]] = User.byId("kazzna") val b: IO[Option[User]] = a.transact(xa) val c: Option[User] = b.unsafePerformIO
これの素晴らしいところは、接続情報がxa
にまとめられていて、それを明示的に渡すということですね。
ちなみにDriverManagerTransactor
の型引数はscalaz.Catchable
を要求してきたりするので、
IO
以外ではscalaz.concurrent.Task
ぐらいしか使える型を知りません。
(きっとガチ勢がコメントしてくれるはず・・・)
テストを書いてみる
最初に書いた通り、SQLが正しいことは確認してからScalaコードを書きたいので、 ユニットテストでDBになんて繋ぎたくないんですね。
ユニットテストで確認するのは「使用したいSQLが出力されているか」までで、 外部との接続はもうちょっと結合度の高いテストでやりたいわけです。
ですが世間一般のライブラリーはいつの間にかDB接続が暗黙的に渡されていたりして、 テストしようと思うと色々なテクニック(モックとか)を使わないと難しかったりします。
ところがこのdoobieはゆるふあ仕様で、それが簡単にできるのです!!!
val a = User.byId("kazzna") // ConnectionIO[Option[User]] val b = a.transK[IO] // Kleisli[IO, java.sql.Connection, Option[User]]
Kleisli[M[_], A, B]
とはゆるふあに言えばA => M[B]
です。
なのでこの場合はb: java.sql.Connection => IO[Option[User]]
ですね。
つまりjava.sql.Connection
を渡せばテストできるわけです。
このinterfaceを実装しましょう。
import java.sql._ import org.scalatest._ class QueryChecker(sql: String, params: Map[String, Any], result: ResultSet) extends Connection with Matches { override def prepareStatement(s: String): PreparedStatement = new PreparedStatement { s should ===(sql) override def setString(i: Int, s: String): Unit = { params(i) should ===(s) } override def executeQuery(): ResultSet = result // override def ... = ??? を必要なだけ書く } // override def ... = ??? を必要なだけ書く } class DummyResultSet(v: List[Map[Int, Any]]) extends ResultSet { var rowIndex = -1 override def next(): Boolean = { rowIndex = rowIndex + 1 rowIndex < v.length } override def getString(i: Int): String = v(rowIndex)(i).asInstanceOf[String] // override def ... = ??? を必要なだけ書く }
気を付けるべきことは、import java.sql._
でjava.sql.Array
がimportされるため、
scala.Array[A]
がArray
と書けないことです。
scala.Array
と全部ちゃんと書く必要があります。もしくは別名import。
あと、closeとかもoverrideしないとランタイムエラーが出ると思いますので、 エラーが出たところから修正していきましょう。
なお、このあたりのコードはJava用なのでmutableに書いたほうが楽だと思われます。
import org.scalatest._ class UserSpec extends FlatSpec with Matches { "Sql" should "be checked by test Connection" in { val id = "kazzna" val query = "SELECT id, password, email FROM users WHERE id = ?" val map = Map(1 -> id, 2 -> "pass", 3 -> "email@example.jp") val expected = Some(User(map(1), map(2), Some(map(3)))) val a = User.byId(id).transK[IO] val b = new QueryChecker(query, Map(1 -> id), new DummyResultSet(Seq(map))) val actual = a(b).unsafePerformIO actual should ===(expected) } }
これでDB接続情報を一度も書かずにユニットテストができました!!簡単!!
例によって例の如くQueryにはCypherを使用していますが、 一応動くサンプルをgithubにあげておきました。
最後に: 教えて怖い人!
ConnectionIO
をOptionT[ConnectionIO, A]
やEitherT[ConnectionIO, String, A]
なんかにして、
2つ3つ組み合わせて途中で失敗したら実行をやめるようなqueryを書くときに型引数つらいのですが、
なんとかなる方法はありませんか?
コメントお待ちしております(>﹏﹏<);;
以上でScala Advent Calendar 2015 12日目は終了です。
お付き合いいただきありがとうございます。
明日はOE_uiaさんによる「Scala AndroidでかDeepLearning的な何か」です。
レベルが高そうですが、楽しみです。
今日から始めるScalaプログラミング!!
この記事はScala Advent Calendar 11日目です。
昨日はdakatsukaさんによるScalaでLuaスクリプトを動かして遊ぶでした。
Luaでしたね!!
ゲーム業界すごいですね!
さて、Scala Advent Calendarですが、まだまだ空きがあります。
難しいことを書かなきゃならないという空気を吹き飛ばすため、
Scalaをやったことのない人向けの記事を書くことによってハードルを下げます。
窓口が広いほど学びも増えるはずです!!
ということで本日はScalaを始めるための環境づくりです。
インストールせずに試す!!
オンラインならIDEONE!
左下のChoose LanguageでothersのところにScalaがあります。
ライブラリーを使わないような入門書のコードなどは、ここで入力して試せますね。
もちろんLuaもあるのでLet's challenge!!
ローカルにScalaコーディング環境を構築する!!
ここからの説明は一番初心者向けということで、 Windows 10ユーザーを想定して進めます。
その他のOSの方はbrewなりportageなり環境にあったものをご使用ください。
Javaのインストール
ScalaはJava VM上で動く言語です。
そのためまずはJavaのインストールが必要です。
JavaにはJavaで作られたプログラムを動かすためのJRE
(Java Runtime Edition)と、
Javaでプログラムを作るためのJDK
(Java Development Kit)があります。
今回はプログラミングを行うのでJDK
ですね。
JDK
にはJRE
が含まれていますので、作ることも動かすことも可能です。
では、「JDK ダウンロード」などで検索してJavaダウンロードページにたどり着いてください。
プログラミングではGoogle力が試されることがよくありますので、
できる限り自力でたどり着くことが大切です。
今回ダウンロードするのはJava SE
(Standard Edition)のJDK
です。
いろいろなJavaが出てきてもう挫折しそうですよね。
細かい名前は覚えなくてもあまりScalaには関係ありません。
さて、ダウンロードページにたどり着くと、さらに多数の選択肢が出て来ます。
今回は最新版(数字が最も大きいもの)を導入します。
Java SE Development Kit 8u66
ですね。
直接Java言語でプログラミングする予定はないので、DemosやSamplesはいらないでしょう。
ライセンスに同意しろと書かれているので、きちんとライセンスを読んだ上で、
同意できるならAccept License Agreement
を選択します。
その下に並んでいるOSの一覧から、自分のOSを選択します。
WindowsにはWindows X86
とWindows x64
がありますが、
自分のOSにあった方を選択してください。
x86かx64かの確認方法
- Windowsのタスクバーの左端「Windowsマーク」を右クリックし、「システム(Y)」を選択します。
- 「システム」が開くので、真ん中ぐらいにある「システムの種類」を確認します。
- ここが「32ビット...」なら
x86
、「64ビット...」ならx64
です。 - その他だった場合は自分でググってください。初心者用ではありません。
Edgeだと、ダウンロードが完了したらそのまま実行が選べます。
インストールは何も考えずすべて「次へ」で大丈夫です。
インストールが終わったら、環境変数Path
にコマンドを追加します。
環境変数の編集はRapid Environment Editorというソフトが使いやすいらしいです。
使ったことはありませんが。
ここでは通常のWindowsの機能でPathを追加する方法を記述しておきます。
既にユーザー環境変数にPath
が存在する場合は、この記事の下の方にある「パスに追加」を見てください。
パスを設定
- Windowsのタスクバーの左端「Windowsマーク」を右クリックし、「システム(Y)」を選択します。
- 「システム」が開くので、左端にある「システムの詳細設定」を選択します。
- 「システムのプロパティ」が開くので、詳細設定タブを選択します。
- 一番下の「環境変数」をクリックします。
- 上段の「ユーザー環境変数」の「新規」をクリックします。
- 変数名に「Path」、変数値に先ほどインストールしたJDKのパスを設定します。
(インストール時にすべて「次へ」を選んでいれば「C:\Program Files\Java\jdk1.8.0_66\bin」です。) - 順番にOKを押してウィンドウを閉じます。
インストールが完了したら、コマンドプロンプトを起動してインストールが成功したことを確認しましょう。
後からやると、どこで失敗したのかわからなくてリカバリーが大変です。
スタートメニューからコマンドプロンプトを起動します。
(同じくマークを右クリック -> コマンドプロンプト(C))
すると、下記のような表示の黒い画面が表示されるはずです。
C:\Users\kazzna>
kazznaの部分はログインしているユーザーのユーザー名になっているはずです。
この部分は勝手に出てくるので、>
より後ろを入力してエンターを押すと入力した内容が実行されます。
さて、インストール成功かどうかの確認です。
こういう場合、普通はversionオプションを使用します。
java
ではなくjavac
なことに注意してください。
C:\Users\kazzna> javac -version javac 1.8.0_66
version番号が表示されれば成功です。
versionオプションは「バージョン番号を表示して終了する」という動作をするプログラムがほとんどなので、 インストールされているかどうかを悪影響なく確認できます。
自分がプログラムを作るときもそういう風にするといいと思います。
javac -version
を実行してもバージョンが表示されずエラーメッセージが出たら?
Javaのインストールの初めからやり直すしかありません。
Activatorのインストール
Scalaでよく使われるツールにsbt
があります。
sbt
を使うと、ライブラリーのインストールやコンパイル・テストなどが簡単にできます。
今回はsbt
にいろいろな機能を追加したActivator
というツールを使用します。
Activator
は内部にsbt
を使用している(らしい)ので、
sbt
でできることはすべてActivator
でできるはずです。
まずは先程と同様に「sbt activator ダウンロード」等で検索して、 Activatorのダウンロードページにたどり着きましょう。
ここでDOWNLOADを選べばWindowsではzipファイルがダウンロードされるはずです。
この記事を書いていて初めて知りましたが、sbt
の500倍ぐらいのサイズですね。
何が入ってるんだろう???
これをどこか好きな場所に展開してください。
「どこか」と言われても初心者は困るでしょうから、
決められない人はコマンドプロンプトの>
より左に書かれているフォルダに展開してください。
展開したら、activator-dist-1.3.7
というフォルダができるはずです。
後ろの番号はバージョン番号なので、もしかしたら新しいバージョンになっているかもしれませんが。
フォルダの中にactivator.bat
が入っていることを確認してください。
このフォルダのパスを環境変数に追加します。
パスに追加
- Windowsのタスクバーの左端「Windowsマーク」を右クリックし、「システム(Y)」を選択します。
- 「システム」が開くので、左端にある「システムの詳細設定」を選択します。
- 「システムのプロパティ」が開くので、詳細設定タブを選択します。
- 一番下の「環境変数」をクリックします。
- 上段の「ユーザー環境変数」にある「Path」をクリックして選択します。
- 「編集」を押すと新規作成と同じようなウィンドウが開きます。
- 既に入っている変数値の末尾にセミコロン「;」を追加した後、
activator.bat
があるフォルダのフルパスを追加します。
(ユーザー名に注意して「C:\Users\kazzna\activator-dist-1.3.7」みたいなのを入れてください。) - 順番にOKを押してウィンドウを閉じます。
コマンドプロンプトを一度閉じて、もう一度開きなおしてください。
そして、以下のコマンドを実行し、Activator
がインストールできたことを確認します。
C:\Users\kazzna> activator --version ~~ もしかしたら何行かのメッセージ ~~ sbt launcher version 0.13.8
バージョンが表示されれば成功です。
Activatorを使ってみよう!!
早速Activator
を使用してみましょう。
まずは作業用フォルダを作成します。
C:\Users\kazzna> mkdir activatorwork C:\Users\kazzna> cd activatorwork C:\Users\kazzna\activatorwork>
最初のコマンドmkdir
(make directory)でactivatorwork
というフォルダをC:\Users\kazzna
に作成しました。
次のコマンドcd
(change directory)で、直下に作成したactivatorwork
フォルダに移動しています。
3行目で左側のフォルダ名が変わっていますね。ここが現在いるフォルダです。
では、まずactivator new フォルダ名
で新しいプロジェクト用フォルダを作ってみましょう。
ここではフォルダ名はactivatortest
とします。
C:\Users\kazzna\activatorwork> activator new activatortest ~~ 何行かのメッセージ ~~ Browse the list of templates: http://typesafe.com/activator/templates Choose from these featured templates or enter a template name: 1) minimal-akka-java-seed 2) minimal-akka-scala-seed 3) minimal-java 4) minimal-scala 5) play-java 6) play-scala (hit tab to see a list of all templates) >
activator new
を実行すると、どのテンプレートを使用するか確認されます。
テンプレート一覧をダウンロードするため、少し時間がかかるかもしれません。
tab
を押すと全てのテンプレートの一覧が表示され、名前か番号を入力すると次に進みます。
今回は4
と入力してminimal-scala
を使用しましょう。
> 4 OK, application "activatortest" is being created using the "minimal-scala" template. To run "activatortest" from the command line, "cd activatortest" then: /home/kazzna/tmp/activatortest/activator run To run the test for "activatortest" from the command line, "cd activatortest" then: /home/kazzna/tmp/activatortest/activator test To run the Activator UI for "activatortest" from the command line, "cd activatortest" then: /home/kazzna/tmp/activatortest/activator ui C:\Users\kazzna\activatorwork>
これでactivatorwork
フォルダにactivatortest
フォルダーが作成されました。
cd
コマンドで移動してください。
C:\Users\kazzna\activatorwork> cd activatortest C:\Users\kazzna\activatorwork\activatortest>
ここからはコマンドプロンプトはこのまま開いたままで、エクスプローラーで作業しましょう。
コマンドプロンプトが得意な方はこのまま作業していただいても構いません。
エクスプローラーを開いたら、アドレスバーにコマンドプロンプトの>
より左の部分を貼り付けてください。
ちなみに、コマンドプロンプトからのコピーは
- 右クリック -> 範囲指定
- 左ドラッグで文字を反転
- キーボードでエンターキーをたーんっ!
です。ご注意ください。
フォルダを開くと、ここにもactivator.bat
などがあるのがわかりますね。
Activator
をインストールしていない人でもプロジェクト途中から参加できるように、なのでしょうか?
ファイルがおっきいので、ここのactivator
から始まるやつは全部消してOKだと思います。
さて、この中身の説明です。
build.sbt
sbtの設定ファイルです。ここにいろいろ書くことでライブラリーやコンパイルオプションなどを変更できます。project
このフォルダの中にsbt自身の設定やsbt用のプラグインの設定を書きます。
今回の記事では触りません。src
この中に自分で作るプログラムのソースコードを置きます。
Activator
がコンパイルしてくれます。src
の中には以下のようなフォルダがあります。
src
のmain
にあるHelloworld.scala
をメモ帳などで開けばもうコーディングが可能ですね。
さて、Activator
を使ってコンパイルしてみましょう。
コマンドプロンプトに戻ります。
C:\Users\kazzna\activatorwork\activatortest> activator compile ~~ 何行か表示 ~~ [success] Total time: 124 s, completed 2015/12/11 1:01:27
初回の起動のみ、いろいろなファイルをダウンロードしてくるので時間がかかると思われます。
次は実行です。
C:\Users\kazzna\activatorwork\activatortest> activator run ~~ 何行か表示 ~~ [info] Running com.example.Hello Hello, world! [success] Total time: 0 s, completed 2015/12/11 1:02:18
同様にテストを実行。
C:\Users\kazzna\activatorwork\activatortest> activator test ~~ 何行か表示 ~~ [info] HelloSpec: [info] Hello [info] - should have tests [info] Run completed in 375 milliseconds. [info] Total number of tests run: 1 [info] Suites: completed 1, aborted 0 [info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0 [info] All tests passed. [success] Total time: 6 s, completed 2015/12/11 1:02:54
ライブラリーを使う
ライブラリーを使いたいときはbuild.sbt
を編集します。
たとえば、MySQLへ接続するためのmysql-connector-javaを入れたいときは、`以下の記述を追加します。
libraryDependencies += "mysql" % "mysql-connector-java" % "5.1.37"
Scalaでjsonを扱うためのjson4sならこんな感じです。
libraryDependencies += "org.json4s" %% "json4s-native" % "3.3.0"
Scalaのライブラリーは%%
、Javaのライブラリーは%
です。
なぜそうなってるのかは気になったらググってください。
このlibraryDependencies
に追加したライブラリーは、
ローカルに無ければ次回のコンパイル時などに自動的にダウンロードされます。
他にもいろいろ機能がありますので、「sbt 使い方」で検索してください。
出てきたコマンドのsbt
をそのままactivator
に変えると動くはずです。
IDEを使ってみよう!
さて、ここまでの内容で既に書いて・コンパイルして・テストして・実行はできるわけですが、 最後にIDEをひとつご紹介しておきます。
有料のUltimateと無料のCommunityエディションがありますが、趣味で使う分にはCommunityで十分です。
仕事で使う場合はライセンスを確認してください。
このIDEA
(アイディア)さん、
なんと先ほどActivator
で作ったプロジェクトをそのまま読み込んで作業できるのです。
設定したライブラリーなども自動で取得してくれます。
sbt-idea
なんていうsbtプラグインもありますが、使わなくても動くので使っていません。
詳しいインストールなどについてはサムライズムさんのブログなどをご参照ください。
Scala Advent Calendar 11日目は以上です。
お付き合いいただき、ありがとうございました。
これを見て「この記事よりかはいいものを書けるぜ!」と思ったあなた!
今すぐカレンダーの空きを埋めるのです!!Qiita版も空きがありますです!!
明日も2日連続で私による「いちばんゆるふあななにかを」です。
まだ何を書くのかを決めていませんが、とにかく「ゆるふあ」に行きます!
まだ決まってないので遅い時間になるかもです。。。すみません。