桧山〜島牧〜寿都〜ニセコ

rinset2006-05-05


5/2〜4 にかけて旅行。
江差の鴎島を見ておきたいというのがあったので、檜山地方のハチャムの森にキャンプを張る。


キャンプ用品は友人と共用のがあったのだが、この度夫婦用に自分達のを買う。
妻はキャンプは始めてだそうで、物珍しがって面白そうにしていた。


2日はウィークデイのため、道もすいていて割りとスムーズにこれた。
しかし、北海道の最南端とはいえこの時期のキャンプは寒い。
朝起きるとテントや芝に霜が降り、外に干していたタオルが凍っていた。
テントで二泊する予定だったが、ちょっと無理だなぁと言うことになる。


とりあえず、2日目の午前中に鴎島へ移動。
妻は海岸でガラスの破片を拾うのに夢中になっていた。
江差なので昼食は寿司にしたが、入った鮨紋はそんなにうまくなく、トリトンの方がうまいねということで意見が一致した。まぁ、江差ならどこの寿司屋もうまいとは限らないということで。


2泊するか、1泊2日で帰るか未定のまま、島牧を目指して北へ向かう。
途中止まった道の駅で安い民宿を発見したので1泊することにする。
しかしテントを持ってきてるのに宿に泊るというのもマヌケな話だ。(寒いんだもん)


3日目、ニセコの黄金温泉へ向かう。
途中、寿都湾の風景が平原、山、海と三つ同時に見れてよい景色だった。
途中蘭越町の路上直売店で妻が実家の両親へタコ、イカ、カレイを発送。


ニセコに着く。
黄金温泉はできてから10年経つそうだが年々湯の温度が下がってきており、現在露天の温度は36.7度という人肌状態。羊蹄山の前景は露天から見えるのだが、湯につかると露天の周囲の庭石にかくれてしまって、湯船につかりながら見るというわけにはいかなかった。湯船からあがると寒いし、行くなら夏がよいです。
混浴だったが、入れ違いに男の客が出て行って夫婦貸切状態だった。


その後ラベンダーファームでシュークリームとアイスクリームを食べた後ふきだし公園へ。
さすがGW。ものすごく人が入っていて駐車場が満車だった。


帰りも割と道がすいており、スムーズに帰ってこれた。
全体的に好天に恵まれ、空気の透明度がよく、風景が良く見れたのがよかった。

支笏・洞爺

rinset2006-04-23



先週に引き続き、温泉へドライブ。
今週は洞爺湖が目標。
妻は洞爺湖が初めてとのこと。


温泉は壮瞥町の御宿かわなみにした。
小さな旅館で露天風呂も小さくぬるかった。
休憩所で持参した弁当を食す予定だったが、休憩所も小さく、物を食べると目立ってしまうので、駐車場で洞爺湖を見ながら食事。


帰りは支笏湖経由で帰る。途中、大滝村できのこ王国による。
ここはきのこ、しいたけを中心とした特産品を売るところなのだが、隣にあるトイレ館と空間が地続きである。(トイレとの間に扉がない)売り場の真ん中に小食堂があって、そば、うどんや、フランクフルトなどを出していた。売り場と食堂の間に自販機が複数あり、食堂でジュースを飲めるようになっている。総床面積は100平米以上ある感じだったけど、これが食堂、売り場、トイレも含めてひとつの空間にある。
温泉の方がたいしたことがなかったので今回のドライブでこちらの方が印象に残った。

隣の敷地には、道の駅があって、「1億円のトイレ」という看板が出ていた。
大滝村はトイレがウリなのだろうか?


帰宅後、あまり腹がすいてなかったので夕食はチキンラーメンですます。
私は食べたのは初めてだが、普通のインランと比べると麺のかみ味がいまいち。

ニセコ

rinset2006-04-16



久しぶりに夫婦でドライブ。


最初は黄金温泉を目指していた。途中2回も民家の門戸を叩いて道を訊いたのに、たどり着いてみると、入浴期間は5〜10月とのこと。でニセコグランドホテルに変更。


露天風呂はかなり広くて景色もよく壮快である。
混浴だったので久しぶりに夫婦で入浴できた。
途中、モテなさそうなあんちゃんが、妻の裸を見ようとだいぶねばっていた。
あと、眼鏡かけたじーさんが、露天風呂に本を持ち込んで読書にいそしんでいたがあれも女性客が来るのを待っていたんだろうか?


帰りに自然学舎でソフトクリーム。吹き出し公園にも立ち寄り、羊蹄山の周りを一周する。
空気の透明度が良く、羊蹄山の全貌が一日中見えた。


夕食は焼肉食べ放題。
2人とも痩せる気があるのだろうか?

Double meaning of "auto"


まずコード

import std.string;
import std.cstream;
import std.windows.charset;

char[] _TEXT(char[] s) { return std.string.toString(toMBSz(s)); }

class C {
	private char[] value;
	this(char[] value) { this.value = value.dup; }
	~this() { dout.writeLine(value); }
}

void main() {
	{
		auto C c = new C("RAII");
	}
	{
		auto c = new C(_TEXT("暗黙の型推論"));
	}
	dout.writeLine("End of main");
}

...
C:\d\test>dmd -run auto
RAII
End of main
暗黙の型推論

何が言いたいかお解かりですね。


で思いついたのが、

	{
		auto auto c = new C(_TEXT("RAII & 暗黙の型推論"));
	}

と書けばどうかっちゅうこと。

C:\d\test>dmd -run auto
auto.d(21): redundant storage class 'auto'

くそ。

	{
		alias auto C CC;
		auto c = new CC(_TEXT("RAII & 暗黙の型推論"));
	}

こう書くとコンパイルは通ったけど

C:\d\test>dmd -run auto
RAII
End of main
RAII & 暗黙の型推論
暗黙の型推論

RAII は実行されてないみたい。

	{
		auto c = new auto C(_TEXT("RAII & 暗黙の型推論"));
	}

これもコンパイルが通らない。


両方やりたければ、class の宣言の方で auto をつければいいと思ったが、

auto class C {
	private char[] value;
	this(char[] value) { this.value = value.dup; }
	~this() { dout.writeLine(value); }
}

void main() {
	{
		auto C c = new C("RAII");
	}
	{
		auto c = new C(_TEXT("暗黙の型推論"));
	}
	{
		auto c = new C(_TEXT("RAII & 暗黙の型推論"));
	}
	dout.writeLine("End of main");
}
C:\d\test>dmd -run auto
auto.d(18): variable auto.main.c reference to auto class must be auto
auto.d(21): variable auto.main.c reference to auto class must be auto

auto な class は RAII の auto 変数でないと、宣言できなかった。
両立はムリのようです。

宣言 - プログラミング言語 D (日本語訳)
ここに

Initializer に前方参照を含むことはできません (この制限は将来的に取り除かれる予定です)。 暗黙に推論される型は、 実行時ではなくコンパイル時に静的に決まります。 クラス参照に対する暗黙の型推論は、 たとえauto記憶クラスが使用されていたとしても、auto宣言にはなりません:

こう書いてありました。

だいたい、キーワードを書かなければいけないのなら全然「暗黙」じゃないと思うんすが。

なかなか進まない


Textiles-FF12-topが更新されてたな。チェックチェック。


自分の方は1日1時間やるかやらないかと言うペースなので、遅々として進まない。
左スティックで動かすのは慣れてくるとスムーズでなかなかよい。
壁にぶちあたると視点が変わるのは困るけど。(地下道とかやたら暗い画面が多いのでブチ当りやすい)


戦闘システムもまぁ慣れてきたかな。
ガンピット任せでも楽なことは楽だが、戦闘中にもキャラ選択して任意のコマンドが入力できることがようやく解った。但し入力のタイミングに注意しないと、アクティブタイムの待ち時間が無駄になる。成長が遅かったのはそのせい。


昨日はセーブポイントが長いことない状態で、長い地下道を進まされた。
将軍は武器も持ってないくせに、やたら敵に近寄って早死にするし。


でもようやくノリが出てきたというか、入り込んできたな〜。

配列の共有

D言語のリファレンスページを読んでいると、なにげに

char[] a = new char[20];

という記述が目に入った。

そっか配列を new する手もあるのだな。
new はポインタっぽいし、動的配列は宣言後追加か、Wikiに載ってる配列リテラルを使ってばっかしいたので、あんまし使わないでいたけど、構築時に領域とれるな。

この方法使うと、3/20に書いた構築時の入力引数と構造体内部の共有はさけられる。
( ~= で配列に追加してもできる)

import house.tostring;

struct S {
	private char[] value;
	static S opCall(char[] value) {
		S s;
		s.value = new char[value.length];
		s.value[] = value;
		return s;
	}
	S dup() {
		return S(value);
	}
	char[] toString() {
		return "{" ~ value ~ "}";
	}
}

import std.stdio;
void main() {
	char[] str = "ABC";
	S s1 = S(str);
	S s2 = s1;
	str.writefln();
	ToString(s1).writefln();
	ToString(s2).writefln();
	writefln("s1.ptr = %0x", s1.value.ptr);
	writefln("s2.ptr = %0x", s2.value.ptr);

	str[1] = 'b';
	s1.value[2] = 'c';
	str.writefln();
	ToString(s1).writefln();
	ToString(s2).writefln();
}

...
ABC
{ABC}
{ABC}
s1.ptr = 900fe0
s2.ptr = 900fe0
AbC
{ABc}
{ABc}

しかし、構造体同士の代入によって内部メンバの配列が共有するのは避けられないですねぇ。dup 使わないと。


お遊びで s1 が持っている配列に追加してみた。

	s1.value ~= "D";
	ToString(s1).writefln();
	ToString(s2).writefln();
	writefln("s1.ptr = %0x", s1.value.ptr);
	writefln("s1.length = %0x", s1.value.length);
	writefln("s2.ptr = %0x", s2.value.ptr);
	writefln("s2.length = %0x", s2.value.length);

...
{ABcD}
{ABc}
s1.ptr = 900fe0
s1.length = 4
s2.ptr = 900fe0
s2.length = 3

おや〜、配列の長さが違っちゃってますな。
s2 の配列は s1 のをスライシングの形で部分的に参照している様。


s2 の方にも追加してみよう。

	s2.value ~= "EF";
	ToString(s1).writefln();
	ToString(s2).writefln();
	writefln("s1.ptr = %0x", s1.value.ptr);
	writefln("s1.length = %0x", s1.value.length);
	writefln("s2.ptr = %0x", s2.value.ptr);
	writefln("s2.length = %0x", s2.value.length);

...
{ABcE}
{ABcEF}
s1.ptr = 900fe0
s1.length = 4
s2.ptr = 900fe0
s2.length = 5

わはは s1 の新しく追加した値が上書きされてる。
length は変化なし。


s1 の方の length を s2 に合わせてやるか。

	s1.value.length = 5;
	ToString(s1).writefln();
	ToString(s2).writefln();
	writefln("s1.length = %0x", s1.value.length);
	writefln("s2.length = %0x", s2.value.length);

...
{ABcE }
{ABcE }
s1.length = 5
s2.length = 5

う〜ん、s2 のはみ出た部分までがデフォルト初期化されてますなぁ。


で、結論。

・動的配列の共有は危険。ptr は共有されるが、length は共有されない。
・共有したいときは、参照用に。共有後、length を変えるようなことをすると、予測のつきにくい動作になる。
・動的に共有したいときは、配列をラップした class を作って(作んのかよ)それを共有すること。

でした。


連想配列は安全に共有できるかな?(今後の課題)

文字列化関数(もう変えない)


構造体だろうが連想配列だろうが何でも文字列化するための関数テンプレートだが、今後とも使用すること多いので、最新版をあげておく。


完全版とは言い難く、static if なんかで分岐するよりも、同名のディスパッチで分けるもんだろうが、本人不都合はないし、一箇所にまとまってた方が本人わかりやすいので、現状これ以上変えるつもりはない。


契約の部分が解りにくいですが、例えば function だったら、

function なのに
型が char[](*)() ではない
ということがあってはならない

という意味です。


これも複数条件をひとつにまとめられるとこあるのは解ってますが、各型に対するのを各自の条件にしてます。

続きを読む