2010年03月25日 01:03

Scalaのメモ その3 関数・演算子

Scalaのメモその2の続き。



関数に返値がない場合、Javaと違って、ScalaではUnitと書く。Javaのvoidと同じ意味かどうかは不明。
def summation(n: Int): Unit = {
	var sum = 0;
	for(index <- 1 to n){
		sum += index;
	}
	println(sum);
}
summation(100);



Unit の場合は、返値型と中括弧 { の前のイコールを省略できる。
def summation(n: Int){
	var sum = 0;
	for(index <- 1 to n){
		sum += index;
	}
	println(sum);
}
summation(100);



引数のない関数呼出は、() を省略できる。副作用を目的とした関数呼び出しは () を省略せず、副作用がなく返値の取得を目的とした関数呼び出しは、() を省略するのがScalaの慣例らしい。
def summation(){
	println(5050);
}
summation;
summation();

副作用のない引数のない関数呼び出しで () を省略する慣例となっているのは、プロパティを取得する方法の実装をメソッドからフィールドに変更しても、それを利用する側のソースコードを変更しなくてもすむように、らしい。例えば、文字列の長さを取得するのは、Javaでは str.length() だが、Scalaでは str.length でもよい。長さの取得がメソッドかフィールドなのかは覚えている必要がない。Javaの配列の長さは arr.length であて、arr.length() でないのは、非常に紛らわしい。() が必要かどうかを覚えるのは手間だ。



for文で使う toIntで定義されているメソッドの扱いらしい。toメソッドの返値は範囲を表す scala.Rainge.Inclusive というクラスのオブジェクト。untilメソッドも同様。以下の4つの例は全部同じ動きをする。
for(i <- 1 to 10){
	out.println(i);
}
val range = 1 to 10;
for(i <- range){
	out.println(i);
}
for(i <- (1).to(10)){
	out.println(i);
}
val range = (1).to(10);
for(i <- range){
	out.println(i);
}



引数が1つのメソッドは、2項演算子と同じ構文で呼び出せる。逆に2項演算子はメソッドの構文でも呼び出せる。2項演算子はメソッドとして定義されている。1 + 2(1).+(2) と同じでシンタックスシュガーに過ぎない。1 to 10(1).to(10) と同じなのもこの理屈による。



2010/03/27追記
その4に続く
タグ:scala
カテゴリ:テック
2010/03/25 Thu 01:03 | Comment(0) | TrackBack(0) | テック | このブログの読者になる | 更新情報をチェックする

2010年03月23日 00:40

Scalaのメモ その2

Scalaのメモの続き。



クラスのフィールにアクセス修飾子を付けなかった場合のデフォルトは public になる。フィールドを隠したい場合は private を付ける必要がある。

クラス定義の本体にフィールド定義と並列にコードを書くと、コンストラクタの中でそれが実行される。
class ComplexNumber(r: Double, i: Double){
	private val real: Double      = r;
	private val imaginary: Double = i;
	println(toString());
	override def toString(): String = {
		if(imaginary == 0)
			real.toString();
		else if(imaginary > 0)
			real + " + " + imaginary + " i";
		else
			real + " - " + (-imaginary) + " i";
	}
}
new ComplexNumber(1.0, 1.5); // ここで生成するだけでクラス定義中の println が呼び出される



Javaのプリミティブ型を1文字目大文字にしたものが、そのままScalaでも使える。Byte, Short, Int, Long, Float, Double, Boolean, Char, StringString はプリミティブ型ではないが)。Javaクラスファイルにコンパイルされるときには、プリミティブ型かラッパークラスに変換されている。



文字列はJavaと同じ構文のほか、Scala独自のものとして raw string 構文がある。""" で囲むとバックスラッシュはおろか改行もそのまま含めることができる。
val s1 = """12345
  67890""";
val s2 = """12345
  |67890""".stripMargin;
1つ目の例は、67890の前に改行とスペースが入る。ソースコードの見た目のためにインデントしたい場合は、2つ目の例のように、先頭に | をつけて、stripMargin を呼び出せばいい具合にしてくれるらしい。



Scalaの等価を調べる演算子 == はJavaでいうところのequalsメソッドと同じで、値が等しいかどうかをチェックしている。型が違っていても拡大変換されて比較されるようだ。
1==1 // true
1==1L   // true
1==1.0  // true
1=="1"  // false



2010/03/25追記
その3に続く
タグ:scala
カテゴリ:テック
2010/03/23 Tue 00:40 | Comment(0) | TrackBack(0) | テック | このブログの読者になる | 更新情報をチェックする

2010年03月22日 00:46

Scalaのメモ

JavaプログラマがScalaを始めたときのメモ。



再代入できない変数(定数?)の設定は、val を使い、再代入できる変数は var で宣言する。
val a = 3;
var b = 4;



ifは文じゃなくて式なので、以下のようにできる。
println(if(1 > 2) 3 else 4)



インクリメント演算子はないみたい。i++ってのでエラーになる。



for文は、構文がJavaと違い、
for(index <- 1 until 100){
}
という感じ。until を使うと99まで。to を使うと100まで。
for(index <- 1 to 100)[
}
で100まで実行される。



2重ループはfor文を入れ子にしなくても、以下のようにforの中にセミコロンで連続して書ける。
for(ii <- 1 to 3; ij <- 1 to 4){
	println( ii + ", " + ij);
}



関数の定義は以下のよう。関数本体の最後の式が関数の返値になる。関数本体のブロック { の前にイコールを忘れないように。イコールを忘れるとなぜか関数本体の中で意味不明なコンパイルエラーが出て、イコールを忘れていることにしばらく気づかなかった。
def summation(n: Int): Int = {
	var sum = 0;
	for(index <- 1 to n){
		sum += index;
	}
	sum;
}
println(summation(100));



関数本体に式が1つしかなければブロックにする必要がない。{ } が不要。以下の2つは同じ意味になる。
def gcd(x: Long, y: Long): Long = {
	if (y == 0)
		x;
	else
		gcd(y, x % y);
}
def gcd(x: Long, y: Long): Long =
	if (y == 0)
		x;
	else
		gcd(y, x % y);



クラスの定義は以下のように。メソッドをオーバーライドするときは、overridedef の前に付ける必要がある。toString はJavaのObjectクラスに定義されているのでオーバーライドになる。
class ComplexNumber {
	var real: Double = 0;
	var imaginary: Double = 0;
	override def toString(): String = {
		if(imaginary == 0)
			real.toString();
		else if(imaginary > 0)
			real + " + " + imaginary + " i";
		else
			real + " - " + (-imaginary) + " i";
	}
}
val c = new ComplexNumber();
c.real = 1;
c.imaginary = -1;
println(c.toString());



不変オブジェクトの例。コンストラクタの引数はクラス定義自体に書く。
class ComplexNumber(r: Double, i: Double){
	val real: Double      = r;
	val imaginary: Double = i;
	override def toString(): String = {
		if(imaginary == 0)
			real.toString();
		else if(imaginary > 0)
			real + " + " + imaginary + " i";
		else
			real + " - " + (-imaginary) + " i";
	}
}
println(new ComplexNumber(100, 120));



2010/03/23追記
その2に続く
タグ:scala
カテゴリ:テック
2010/03/22 Mon 00:46 | Comment(0) | TrackBack(0) | テック | このブログの読者になる | 更新情報をチェックする

2010年03月15日 22:07

3月15日のパキラ

Image340.jpg
いまは隣の人に世話を委託しております。
カテゴリ:植物成長記録
2010/03/15 Mon 22:07 | Comment(0) | TrackBack(0) | 植物成長記録 | このブログの読者になる | 更新情報をチェックする

2010年03月12日 20:49

巨大なファイルを一定のサイズで分割する方法

splitというコマンドが使える。大きなファイルをサイズを指定して分割できる。

巨大なファイルをWindowsパソコンの外付けハードディスクにダウンロードしたら、4GBぐらいで書き込みエラーになる、という罠にはまって、調べた。

以下の例では、巨大な backup.tar.gz というファイルを1GBごとに分割するコマンド。分割して結果できたファイルは、backup.tar.gz-00backup.tar.gz-01backup.tar.gz-02…というファイル名になる。元のファイルは削除されずに残る。
split -b 1073741824 -d --verbose backup.tar.gz backup.tar.gz-
-b はサイズを指定する。1073741824というのは、1GBが1073741824バイトだから。
-d は生成されるファイル名に連番を付ける。これがないとアルファベットがつくが、日本人には数字のほうがいい。
--verbose があると途中経過が表示される。なくてもいいけど、大きいファイルの処理だと時間がかかるので、あった方が安心する。
その後は、元のファイル名と、分割後のファイル名のプレフィックス。

結合するのは単純で、以下のようにする。backup2.tar.gz を生成している。
cat backup.tar.gz-* > backup2.tar.gz
タグ:Linux
カテゴリ:テック
2010/03/12 Fri 20:49 | Comment(0) | TrackBack(0) | テック | このブログの読者になる | 更新情報をチェックする

2010年03月09日 20:34

Ubuntu に nagios をインストール

Ubuntu に nagios を apt-get でインストールした。
sudo apt-get install nagios2 nagios-images nagios-plugins

ブラウザでアクセスするためのBASIC認証のパスワードが /etc/nagios2/htpasswd.users に設定されているので、このファイルに適当なIDとPWを設定する

これで http://localhost/nagios2/ にアクセスすればいいと思ったが、アクセスするとページによっては以下のメッセージが出てしまう。赤字ボールドで表示される。(そんなに強調しなくてもいいのに。)

It appears as though you do not have permission to view the configuration information you requested...



いろいろ調べたら、/etc/nagios2/cgi.cfg の中にたくさん nagiosadmin というIDが設定されており、これと /etc/nagios2/htpasswd.users で設定するIDを一致される必要があるみたいで、 /etc/nagios2/htpasswd.usersnagiosadmin を設定しなおしたら、エラーメッセージが表示されなくなった。


あとは、/etc/nagios2/conf.d の中のファイルを適当にいじれば良さそうだ。ファイルをいじったら、
sudo /etc/init.d/nagios2 reload
とする必要あり。
タグ:nagios Linux
カテゴリ:テック
2010/03/09 Tue 20:34 | Comment(0) | TrackBack(0) | テック | このブログの読者になる | 更新情報をチェックする
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。