水は天敵であり餌でもある

ついに夏休みも終わりですね。
というわけで、音楽をD-Snapに転送し直してたのですが、えらい時間かかる。
800曲強あるんですけどね。いや時間がとにかくかかる。
アーティスト名の整理のために転送し直してたんですけどね。
ただ1つだけ忘れていることがあった。駐輪場の更新(というか再開)だな。明日事務所に行けばいいでしょう。


いや、早明浦ダム、えらいことですね。
四国というのはそれほど大きくない島ですし、雨も多くはない。
水の融通というのは非常に難しい問題で、それを解決してきた早明浦ダムでございます。
吉野川、なんか紀の川の一部もこう言うけど、こちらは四国にあります。
暴れ川として有名でその治水のために、そんな意味もあって作られたダムでもあるようです。
有効貯水容量は2億8900万m2とあるが、これはとんでもなく大きいですよ。
高山ダム、ダム湖の月ヶ瀬湖の方が有名かも知れんが、あれは4920万m2だからね。
それは今までのため池よりも強力な水源となるようにというので作られたのでしょう。
まぁ実際これのおかげでかなり改善されたようでして、渇水も減りましたしね。
ただそれでも最近は渇水が起きていると言うことです。


さて、調べてみるとこう言うことらしい。
早明浦ダムの水は下流に流されて池田ダムに達する。
ここから香川用水と吉野川北岸用水が分岐する。
吉野川北岸用水は徳島県内で農業用水として使われるのか。
このまま吉野川は徳島県内を流れていきますから、まぁ結構いろいろ使われていると言うことです。
香川用水は言うまでもなく香川県内に流しています。
これはかなり重要で、大きな川もないところなので、香川用水への依存度はかなり高いと。
早明浦ダムの貯水率0%を切っても、発電用水を供出させて水道水だけでも作らないと本当にまずいと。
どうもそういうところらしいです。
もっとも、節水させるためにかなりいろいろやっています。水圧を下げたりなんやら。
ただ、吉野川は香川県内を通らない。渇水時、そもそも吉野川の通る徳島県と争いになるそうでして。
いや大変なことです。
ちなみに高知県は早明浦ダムがあるところなのですが、あんまり関係ないらしい。
多分下流の方で細々と使うのがもっとも重要なのかも。いや、高知分水ってのがあるみたいだけどね。
愛媛県は吉野川の支流の銅山川の方にダムを作ってこっちで融通しています。
ただし、本来銅山側から下流に流さないといけない水を、早明浦ダムが肩代わりするという方法で間接的に水を供給していると。そういうことです。
なかなか難しいわけですが、まぁ一番ひどいのが香川用水を使ってる人たちですよね。
肩身狭いしねぇ。しょうがないんだけどね。


よりいっそうの節水に励んでいただくしかないわけですが、まぁ水とは難しいもんです。
紀の川の上流も吉野川というのだが、そこも関係があるわけだが、
奈良盆地に水を供給するにはどうすればいいかというので昔いろいろあったそうだ。
まぁこれもなかなか大変なことだったみたいですよ。紀の川も相当に水不足になることが多いらしくて。
農業用水ですね。まぁとにかく大和川の水量が足りんと。
どうも、現在は紀の川の上流に大迫ダムと津風呂ダムを作って、下渕頭首工で水を奈良盆地に送る。
けどこれでは紀ノ川の水が減りすぎる。その分を十津川(熊野川の上流)から回すと。
まぁえらいことですね。猿谷ダムから水路で紀の川に持って行くと。
最終的に誰が損をしたのかというと、奈良県の熊野川流域の人々ですね。
木をいかだ流しで下流の新宮に運んでいたのですが、水量が減って、できなくなった。
そういえば今はヘリコプターとトラックで木を運んでますね。金はかかるが、手間が少なくて現実的な話だそうです。
まぁ水とは厄介なもんです。

普通は役に立たんstructだな…

今日、C#のプログラムをいじくってました。
主に構造体がいいかクラスがいいかの問題。
構造体は変数が実体、クラスは変数の他に実体がある。
そんなわけで構造体の型を値型、クラスの型を参照型と言うわけだな。
C#ではこの2つの扱いが非常に似ていますが、実際はとんでもないことです。


構造体は粘土玉、クラスは風船だろうか。
粘土板は粘土をちぎるだけで作れる、一方風船はふくらませるのに時間がかかる。
しかし実際は風船は軽い。持ち運びには風船はいい。
これについて実験した資料がある。
時代錯誤に今更こんなことを検証するのかよ! C#で何バイトなら構造体にして許容できるか? (Smart Way! オータム マガジン)
16Bytesが境界みたいだね。予想よりもクラスは有利なようだ。
他にクラスの利点は、継承ができること、参照渡しであること。
この参照渡しであると言うことはそれはそれで悩ましい問題だけどね。


さて、いろいろ実験してたのだが、やはりクラスというのは優れている。
構造体にすることで性能が上がるかという実験をしてました。しかし結論はクラスがいいと。
もともと構造体だったものまで一部見直してクラスにするぐらいです。
一見、Dictionaryのキーを参照型にするのはアホにしか見えないことだ。
しかし、実際は参照型を使った方が性能をいい。
うーん…参照型前提で作られてるのかな。値型と参照型の行き来はちょっとあるからねぇ。
それともう1ついいのが、継承という考えがあること。
fooクラスがbarクラスを継承していたら、次のようなことをしてもfooクラスのインスタンスmyfooの実体の変化は何もない。

bar mybar=myfoo;
foo anotherfoo=(foo)mybar;

構造体には継承という考え方がないから、値型同士の行き来をしようとすると、
型変換演算子を作らないとできない。けどそうすると実体を何度も作ったりといろいろ困る。
インターフェースは、参照型だしねぇ…
まぁこんなところを見てても、値型は非常に息苦しい。


まぁ難しいことを言ってるのだが、
結論から言えば、構造体を使って性能が上がることはほとんどないから、クラスを使うのがいいでしょう。
そういうことなんだと思います。
今日いろいろ試したけど、構造体を使って性能が上がった気がする出来事なんか無かった。
まぁそんな構造体、何がいいのかというと、違う変数に代入するだけでコピーできることでしょうか。
なんか間違ってる気がするけどね。

原稿用紙で文字をきれいに並べるよ

今日はちょっとレポートを書いてた。
夏休みの宿題ですね。例によってOpenOffice.org。
やりたかったことがあった。それは文字数がわかりやすいように文字を配置すること。
実は2000字以上で書いてこいということだったので、1行の文字数を制限しようとおもったわけだ。
いや、しかしあまり得意じゃないネタで2000字も書くのは大変ですわ。
そうすればかけ算で簡単に証明できる。もっとも文字カウント(ツールにある)で作ってる方はわかりますけど。


やり方は簡単です、
ページスタイルの行数と文字数で行数と文字数を指定する、とすればいいだけです。
1行の文字数は文字サイズ12ptだと、35文字程度にとどめた方がいいかな。
40文字にしたければ11ptぐらいにするべきでしょう。じゃないと窮屈すぎる。
ページ単位の行数はフッター・ヘッダーの分考えて限界で止まる。
ただ、ルビを書かないならば、ルビの最大サイズを減らせばページ単位の行数を増やせる。
ここでポイントだが、あらかじめ文字を何行か打っておいて少しずつ減らして、崩れるほどは減らさないこと。
4ptが限界だった。すると行数は増やせる。
フォントは等幅フォントを選ぶといいと思う。ただプロポーショナルフォントでも行きますけどね。
ちなみに原理は文字が罫線に合うように調整されるから文字数が制限できると言うこと。
なのでアルファベットをたくさん打つと調整はうまくいかなくなる。あFooいと打つと、Fooで2マス使う。
まぁ結構不気味ですね。まぁあくまでも行数・文字数制限は漢字圏向けのものでしょうかね。


さっきの原理からもわかるように、大きな字でタイトルを書けば、三行分使ってくれたりする。
もちろん改行した行はぴったり罫線に合う。すばらしいですね。
しかし、印刷するときには罫線を外すことにした。
PDF出力のことを考慮すると編集完了後、罫線を表示するを外せばいいと思う。
そうやってできたレポートを見て思ったのは、不自然に字間が調整されてるなぁという印象ぐらいだった。
まぁ整然と並んでますね。思ったよりはいい感じです。
もちろん罫線を表示すれば、原稿用紙っぽくなりますけどね。


ところで、以前から思ってたのだが、原稿用紙ってその使い方の都合上空白マスが生じますけど、
これを考慮する必要はあるのかな?もしかすると占積率みたいなのがあるのかな?
1行20字の原稿用紙と1行26字の原稿用紙なら後者の方が占積率は低いだろうな。
まぁそれを考慮して、出版社は原稿を書いとったりしてるのかも知れないけど。
しかし、コンピュータの方では、文字数数えるのめんどくさいから、
Shift_JISで改行コードCR+LFのプレーンテキストのファイルサイズで言いますよね。
僕はUTF-8使ってるから、あんまり身近じゃないけど、TeraPadで開いてF4すれば表示される。
けどこれはエンコーディング関係なくShift_JISのサイズなんだよね。なんか不思議な感じ。
この慣習は世の中がUnicodeに染まっても残るでしょうね。
なんせ、U+FF00~U+FFEFの間に登録されているカタカナのことを未だに半角カナと言うのだから。
もうそんなものは存在しないんですよ。けどそういう習慣は今も残ってますからね。
コンピューターで一番簡単な文字数のカウント方法は、UTF-32で改行コードLFで保存してファイルサイズを調べると。
1文字4Bytesだから、それで改行は1文字と数えますと説明すればまぁわかる。けどUTF-32ってどんなけマイナーやねん…

インターフェースは無力なのが強いという結論

Rubyの機能にMix-inというのがあるらしい。
これは、多重継承を可能にする物だという。
多重継承とは1つのクラスが2つ以上のクラスを継承すること。
Java・C#では禁止されている。ただし、インターフェースという作るメソッド・プロパティを定義するだけのものは何個も実装できる。
すなわち、メソッドなどの内容を継承できるのはただ1つのクラスだけということ。
C#でIEnumerableインターフェースを実装する。けどそれだけでは何も起きない。
IEnumerableを実装したのを取り扱うことができる、foreachとかがあるから役に立つ。
しかし、RubyのEnumerableモジュールは違う。eachメソッドを定義して、取り込みを行う。
するとeachメソッドがあるのを前提に作られた、Enumerableモジュールのメソッドたちが読み込まれる。
結果、x.sortなどのような便利な取り扱いができる。


このモジュールというのがMix-inという機能を象徴している。
モジュールは、専ら取り込んで使われ、それ自体のインスタンスは存在しない、モジュールは継承をしない。
とまぁ、そんなもんです。
これは、多重継承で起きる菱形継承問題をうまく回避している…らしい。
菱形継承問題とは、こういう問題。
Aクラスに仮想メソッド(継承したクラスがオーバーライドできるメソッド)fooが定義されています。
これを継承したBクラス、Cクラスは共にfooメソッドをオーバーライドして内容を書き換えました。
DクラスはBクラス・Cクラスを共に継承しました。このときどのクラスで定義されたfooメソッドが実行されますか?
実際は優先順位を決めて行うことが多いけど、曖昧なのでJava・C#などでは禁止されています。Rubyも。
菱形継承問題については、互いに全く同じクラスを継承しないクラスたちを継承すればいいような気がする。


なるほど、それで継承することを禁止されたモジュールがあるわけですか。
これを見ていると、インターフェース内部にメソッドの内容を定義することに問題ないように見える。
まぁC#のインターフェースはインターフェースを継承するんだけどね。
うーん、これは結構な足かせだな。ここで菱形継承問題を起こしては何も意味がない。
インターフェースを継承しないインターフェースのみ、メソッドの内容を定義できる。
もしくは、インターフェースAを実装したインターフェースのみがインターフェースBを実装できると、
そういうことをBに定義すれば、Bを実装したクラスはAを実装していると知っているので、Aの機能をB内部のメソッドが活用できる。
非常に下品な制度だが、多分菱形継承ではない。
とまぁ、こうすればRubyのモジュールと大差ない。しかし、そんなものにインターフェースの名は与えんだろうね。
もっともこういうことを実現しようとして、C# 3.0の拡張メソッドは作られたわけだけどね。
けど拡張メソッドはわかりにくいしねぇ。


まぁなかなか難しい問題なのだが、多重継承にはもう1つ問題がある。
それはメソッド名が重複してしまうこと。これはRubyのモジュールと同じかな。
Perlでは継承するメソッドを指定しますけどね。それだけを継承すると。
C#でインターフェースの実装で実験してたが、これはこういう風に解決していた。

string Ifoo.method() {
return "Ifoo経由で呼び出した場合はこれ";
}

すなわち、obj.method()と、((Ifoo)obj).method()の結果は違うと言うこと。
前者は、objが基底クラスから継承したmethodメソッド、後者はそのクラスで定めたIfoo用のmethodメソッド。
なるほど、この程度だからこんな解決ができるが、Rubyのモジュールのような制度はこんな風には行かない。
その名前のメソッドがなければ、メソッドを取り込むといういい加減な解決はあまりよくない。
だって、そのクラスに急にその名前のメソッドが追加されるかも知れないから。すると予想とは違うことになる。
もしモジュールが実施されても、((Ifoo)obj).method()のような呼び出し方しかできないかもしれない。
そう考えると、C#がRubyのモジュールのようなものを導入せずに拡張メソッドという中途半端なもので納得できたのかわかる気がする。
拡張メソッドはあくまでも代用表現だからね。a.extmethod()は、extclass.extmethod(a)のように表現するのと一緒だし。

.NETというのだからXMLは当然のことか

XMLというと、非常に自由に記述できるイメージがあるけど、それは間違えかも知れない。
というのも、XMLはSGMLの機能制限版というようなものだから。
SGMLはとても複雑でその機能を使い切ることは不可能で、完全に解釈するパーサーは少なかったと。
それを整理して、扱いやすくて解釈しやすいものを作った、それがXML。
それでも、非常に自由に記述することができるイメージがあるということは、SGMLが相当ひどかったということだな。
なのでXML文書は同時にSGML文書です。だからSGMLのDTDをXMLでも使うことがあるのか。
ただ、SGMLには無かった名前空間という考えもあるし、というのでXML Schemaを設計中だとか。
実際、SGMLで書くHTMLと、XMLで書くXHTMLを見比べても、あまり差はない。
空要素は<br />のように記述する、ルート要素たるhtml要素にxmlns属性を付けて名前空間を指定する程度の違いしか見えない。
ちなみに、空要素の記述法はSGMLの仕様にあるものを応用して作ったそうです。けど根拠がわからん。
という風に、非常にSGMLは複雑だったのですが、XMLは普段使うものに限って残したからかなりシンプルらしい。
そんなXMLだが、非常に扱いがいいので、多くのところで使われている。
.NET Frameworkでは従来iniファイルを使って記録していたこともXMLで記録するのが推奨されている。


ただXMLの解釈にはいい思い出がない。えらい苦労した。
しかし、それを非常に簡単に処理できるSystem.Xml.XmlDocumentクラスがあるんですね。
これ.NET Framework 1.0の時代からあるはずなのにね。なんでこれを紹介するページを見つけられなかったんだろ。
これは、DOM(Document Object Model)というAPIを.NET Frameworkが実装したもの。
この方法の特徴は、XMLファイルをツリー構造で扱うこと。
なので、こんな風に簡単に扱える。

const string xmlns="http://libserver.ddo.jp/fdiary/index.php?e=105";
xd.DocumentElement["Profile",xmlns]["Name",xmlns].InnerText

xdはXmlDocumentのインスタンス。
DocumentElementはルート要素のこと、[“Profile”,xmlns]は、http://libserver.ddo.jp/fdiary/index.php?e=105 名前空間のProfile要素。
…こんな風に扱えるわけです。
ただし、この方法はツリーを作ってから操作することになるだろうから、動作が遅いとか。
XMLもSGMLに比べれば簡略化されたとはいえ、解釈にかかるパワーは未だに大きいとか。
そんな処理を一旦してから、ツリー構造をメモリ上に置いておいて、そこから処理すると。
他にSAX(Simple API for XML)というAPIも有名らしいが、
これは要素を読み取ってはイベントに投げるということを行うものだそうだ。
こちらの方が軽量だけど、さっきのような記述法は通用しないでしょう。


さて、その前に少し勉強しておかないといけないことがある。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Profiles [ <!ENTITY NaraShi "奈良県奈良市">
<!ENTITY SeikaCho "京都府相楽郡精華町"> ]>
<Profiles xmlns="http://libserver.ddo.jp/fdiary/index.php?e=105">
<Profile>
<Name>中山次郎</Name>
<Birthday Year="1989" Month="10" Day="20" />
<Address Zip="619-0238">&SeikaCho;精華台八丁目1番地3</Address>
</Profile>
<Profile>
<Name>杉&#30000;祐介</Name>
<Birthday Year="1991" Month="7" Day="6" />
<Address Zip="630-8012">&NaraShi;二条大路南一丁目1番1号</Address>
</Profile>
</Profiles>

これはXML文書です。いろいろ考えたのだが、こういう文書が解釈しやすい。
まず一番始めにXML宣言。次にDOCTYPE宣言、普通はここでDTDを指定しますが今回はしません。
DOCTYPE宣言の[ ]内で、ENTITY宣言をしています。これは実体参照を定義しています。
&NaraShi;と書くことと奈良県奈良市と書くことは一緒であると定義しているわけだ。
XMLにおいては、&lt;,&gt;,&amp;,&quot;,&apos;の実体参照、&#60;,&#xFFEF;の数値参照はすでに定義されています。
ちなみに&#30000;は10進数で書いた場合、&#x7530;は16進数で書いた場合。
これが表す文字はUnicodeでU+7530のなんだが、田という字だ。切りがいいので覚えておくとおもしろい。
それ以外はDTDで定義することになる。今回&NaraShi;と&SeikaCho;を定義している。
何度も長いのを書くのがいやだから実体参照を定義するというのもあるけど、
もし、京都府相楽郡精華町が、京都府精華市に化けたとき、ちょっと変えるだけで変更が反映される。
そういうメリットもあります。こういうのを内部実体参照と言う。
あと、外部ファイルを読み込む実体参照もあって、これは外部実体参照と言うとか。
さて、次にルート要素。XML文書はルート要素を1つ持つということなので、1つだけ持つ。
ルート要素にxmlns属性を付けているが、xmlns属性で名前空間を指定すると。
この名前空間にはURIを指定する。今のところURIはURLとURNの総称だな。とりあえずこの記事のURLを指定した。
特に意味はなく、XML要素たちの依り代程度の意味です。XHTMLの要素はhttp://www.w3.org/1999/xhtmlという名前空間に属すると。
これがURLだとしても、そこに何があっても関係ない。何もなくてもいい。
xmlns属性を指定したら、その要素と、子孫の要素は何もしなくてもその名前空間に属する。
xmlns:foo属性を指定したら、のように記述した要素は、その名前空間に属すると。
どれも正しい書き方でして、まぁいろいろあるということです。
ところで、要素ノードは0個以上の属性ノードを持って、子として要素ノード・テキストノード・コメントノードなどがあると。
まぁこんな風なツリー構造になってると。
ここで重要なのは属性ノードに値があるんじゃなくて、その下のテキストノードとかに値があるということ。
その子孫のテキストノードの値を連結したものを得るInnerTextがあるから、それを使えばいいけど、子孫だというのが厄介。
まぁそんなところを見ると、こういうXMLは解釈しにくいと思った。

<Address>
<Zip>630-8012</Zip>
&NaraShi;二条大路南一丁目1番1号
</Address>

Addressの値を示すテキストノードと、Zip属性の属性ノードが混在している。
これでInnerTextを取得すると、630-8012(空白改行)奈良県奈良市二条大路南一丁目一番一号のような値が返ってくる。
なるほど、確かに困る。いろいろ実験してたが、これを解決する画期的な方法は見つからなかった。


さて、これを解釈するプログラムを作成してみた。

System.Xml.XmlDocument xd=new System.Xml.XmlDocument();
xd.Load(@"..\test.xml");
const string xmlns="http://libserver.ddo.jp/fdiary/index.php?e=105";
System.Text.RegularExpressions.Regex space=new System.Text.RegularExpressions.Regex(@"\s+");
foreach (System.Xml.XmlElem ent curprof in xd.DocumentElement.GetElementsByTagName("Profile", xmlns)) {
System.Console.WriteLine("氏名 : {0}", space.Replace(curprof["Name", xmlns].InnerText, " ").Trim());
System.Xml.XmlAttributeCollection attrs=curprof["Birthday", xmlns].Attributes;
DateTime birthday=new DateTime(int.Parse(attrs["Year"].Value), int.Parse(attrs["Month"].Value), int.Parse(attrs["Day"].Value));
System.Console.WriteLine("生年月日 : {0:yyyy年MM月dd日(ddd)}", birthday);
System.Xml.XmlNode addrnode=curprof["Address", xmlns];
System.Console.Write("住所 : ");
System.Xml.XmlAttribute zipattr = addrnode.Attributes["Zip"];
if (zipattr!=null) {
System.Console.WriteLine("〒{0}", space.Replace(zipattr.Value, " ").Trim());
System.Console.Write(" ");
}
System.Console.WriteLine(space.Replace(addrnode.InnerText, " ").Trim());
}

ところで今回/\s+/の正規表現のメソッドを始めに作って、space.Replace(mystring, ” “).Trim()のような操作を何度かしている。
これはHTMLの解釈をマネして付けてみた。
HTMLでは連続する空白文字は1つにまとめられて、どれもスペースで表示される。
ブロックレベル要素の初めと最後のスペースは消える。この2つを再現してみた。まぁどうでもいいことなんだけどね。
まずXmlDocumentクラスのインスタンスを作り、XMLファイルをLoadする。
xd.DocumentElementでルート要素のノードを取得する。
さて、要素ノードは、foreachで子ノードを1つ1つ回すもよし、
elem[“foo”,xmlns]のようにfoo要素である子ノードを1つ取り出すのもいい。
GetElementsByTagNameメソッドは、その名前の要素が2つ以上あるかもしれないとき使う。
これでProfile要素たちを取り出してforeachで回すことにした。
要素の属性ノードは、elem.Attributes[“foo”]のように取り出す。
属性の値はValueプロパティで得られる。
要素の子孫のテキストノードの値は、さっき言ったように、elem.InnerTextのようにInnerText属性を見るのがいいと思う。


こいつの機能は非常に豊富でXML文書を作成、編集することもできる。
ノードの取り出しも、高機能な問い合わせ言語である、XPathを使って行うこともできる。
まぁそんなわけで非常におもしろい。
ただ、厄介なのが型の名前のこと。
要素ノードはSystem.Xml.XmlElement、属性ノードはSystem.Xml.XmlAttributeのようにいろいろある。
もし、GetElementsByTagNameメソッドとかで、要素ノードだけを取り出せると知ってる時はこれを使う方が何かといい。
ちょっと機能が豊富。GetElementsByTagNameメソッドはSystem.Xml.XmlElementクラスにしかないし。
ただ一方、要素自体をforeachで回すときは要素ノードだけじゃなくてテキストノードとかいろいろ沸いてくる。
そういうのをひっくるめて、System.Xml.XmlNode型で表すんですけどね。これは抽象メソッドだったはず。
扱いが悪いというのならば、elem.GetElementsByTagName(“*”)のようにするのがいいのかな。
多分こっちの方が何かといいと思います。
まぁそのあたり気をつけながらやると多分うまくいくと思います。

JRの切符は信じられない運賃を出してくるらしい

C#でXMLを簡単に解釈できて驚いた。今まで知らなかったのがあほらしい。
しかし今日はその話ではなくてJRの摩訶不思議な運賃制度の話。
今度、旅行しないと行けないの。
けど10円でも安く快適に行けるとうれしいなと思うわけです。
まぁそういうわけで必死になって探してたが、随分ひどい。
特に学校の用事なので、学割証をもらうつもり。
しかし、当然学割証には関係ないルートは書いてもらえない。
例えば、柏の人が、受験かなんか知らんが、南草津駅まで行かないと行けない。
そのとき、柏駅~南草津駅の学割証は出るだろうが、もし大阪まで欲しいと言ってもそれは無理でしょう。


JRの運賃の不気味なところはすべての運賃はこれで計算できると言い張ること。
賃率×距離
しかし、この方法はあまり現実的じゃない。10円単位に切り上げるにせよ無数に切符を用意しないといけない。
確かに今なら、コンピュータに打ち込んだら、すぐ出せるけど、昔はストックから出してきてたと。
実際は、近距離の運賃があまりに現実離れした数字になるので、10kmまでは特に定めていますが、
それ以上は11~15kmと、5km刻みで50kmまで、51~60kmと10km刻みで100kmまで、101~120kmと20km刻みで600kmまで、601~640kmとそれ以上は40km刻み、
距離はこの中間距離、11~15kmであれば13kmを採用して、計算する。
100km以下は10円以下切り捨て、101km以上は十の位で四捨五入して100円単位にすると。
ただし、これを定めた後に追加したのだろうか、この結果を1.05倍して、一の位で四捨五入して10円単位にするとなっている。
例えば、京都~金沢は225km(1km未満は切り上げ)で、これは221~240kmの範囲に当たり、中間距離は230km
全部幹線で、300km以下なので、1kmあたり16円20銭なので、230*16.20=3726円、十の位で四捨五入して、3700円。
これを1.05倍すると、3885円で、一の位で四捨五入すると、3890円となるわけです。
ただ、実際はさらに複雑なので、表を見ないとわかったもんじゃないが、中間距離を採用するというのは重要なところ。
駅すぱあとで、分割すると安くなる駅を計算してもらった。
これによれば、京都~マキノ・マキノ~金沢に分割すると安くなる。なぜか?
京都~マキノは67km、マキノ~金沢159km、それぞれ61~70km、141~160kmに当てはまり、65km、150kmのが採用される。
さっきの230kmと比較すると、215kmとかなりの節約になることがわかる。分割すると260円安くなるとある。
こういうことは近鉄とかでは起きないんですね。
実際の式は知らないけど、距離×賃率+一定 になってるんでしょう。この一定が十分多ければ分割は流行らない。


まぁ正直、これだけなら大した問題ではありません。
確かにこれが問題になることはありますが、実際は長距離になると賃率が変わります。
300kmまでは16.20円、けど301~600kmの分は12.85円で計算されますから。
300*16.20+(L-300)*12.85のように計算されますから、長い距離を1枚の切符にすると何かと有利でしょう。
ただ、長距離になると刻みの大きくなるから、たまにヒットしますけどね。
実際これより問題なのは、特に安い運賃をある区間内でだけ適用する場合。
電車特定区間という区間があるらしい。もちろん、ディーゼルカーに乗っても適用されるでしょうね。無いと思うけど。
というのも、電車特定区間内で完結するときだけ、特に安い賃率を適用するから。
例えば、大阪~山科は820円だけど、大阪~京都は540円、山科~京都は180円、結果京都で分割すると100円安くなる。
これは京都までが電車特定区間だからというのが原因だが、変な話だ。
さっき言った通り、JRの運賃は一定分が小さい。だからこんなしょうもない分割でも十分安くなる不思議。
あと、このルールで計算した運賃が異常に高いとき、特別の運賃を適用するときがある。
けど、これもその区間だけを利用するとき特に安くするのだから、そこ以外を含んだら対象外と。
まぁそんなこともあります。


ここまではJRを普段使う人なら使ってるかも知れない。
特に定期券は二枚分割定期券の人も結構多いらしいです。
これは普段とは関係ない話。
京都~熊谷の切符を買うと、578kmで8720円になるみたい。
往復買うと、安くなりそうなもんだ。しかし対象は601km以上。ケチな話だ。
こういう601kmに満たないと思ったら、ちょっと距離を伸ばす。
京都~高崎にする、これは618kmで、601~640kmに当てはまる、ちょうど601kmを越えた初めての料金帯と。
これの運賃は9350円なのだが、往復割引ではそれぞれ1割引(10円未満は切り捨て)で8410円になる。
片道で310円安くなる。往復で620円ですね。
もっとも今回は30kmも距離を伸ばさないといけないから、あんまりお得になった気がしないけど、
あと少しなのに…ってときにやると随分安くなる。


実は、今回計算してたら、まさにこれに引っかかったんだよね。
学割は往復割引の金額からさらに割り引くことができるから。
なので、ちょっと距離を伸ばしたのだが、不気味なことこの上ない。こんな学割証が出るのだろうか。
まぁまた相談してみるが、こちらの方が安いのであるとなれば、
「修学上の経済的負担を軽減する」制度に反することもないので、不気味な学割証も出ると思うけどね。
実のところどうなんでしょうか?

熱した金属材料はセールスマン革命を起こす

巡回セールスマン問題の解法について研究中です。
以前の記事で取り上げたとおり、巡回セールスマン問題は「最適解を求めることはあきらめましょう」という難問です。
もっとも今回考える120箇所程度の問題であれば最適解は求まるんですけどね。けど時間かかるし。
いろいろやったところ、焼きなまし法は非常に安定していい結果が出せることがわかった。
あくまでいい結果で最適解ではないですね。事実これまでの方法で最適解と思っていたのよりずっといい結果が出たので。
まぁそんなわけでさらにいい結果が出せる方法を探して行けたらいいとおもうけどね。


さて、以前、2-opt法とか書いたがあれはちょっと間違い。
あれは入れ替えの方法じゃなくて、入れ替え候補の作り方ですね。
前回やった方法も、今回やる焼きなまし法も、局所探索法と呼ばれるものの1つで、
まず、ランダムに解の候補を作成する。もっともランダムに作った答えなので結果は散々でしょうね。
さて、これを少し変更した近傍解というのを作る。この方法が2-opt法とかOr-opt法とかだ。
この近傍解が解の候補よりも優れていれば入れ替える。これを繰り返してよい解を見つける。
これが前回の方法で、山登り法と呼ばれる方法です。
どのへんが山登りなのかというと、まず山を発見する。これがランダムに作成した解の候補。
これをとにかく登っていく。それで高い山に登れればいいのですが、運悪くその山が天保山ならばうれしくもなんともない。
それを回避するために僕は何度も計算してよい結果を取ろうとしたわけです。
実際ひどい有様で、10回計算して、その中でもっとも成績がいいのは335移動ぐらい、まぁ毎度違うんだけど、
ところが、毎度そんな結果が出るわけでもなく、悪いときは350移動ぐらいの答えがもっとも成績がいいと。
まぁそんなわけで、なかなかうまいこと成績を出せないわけですよ。
それに10回計算すると時間もかかる。特に、Or-opt法は点の数が増えるとものすごい時間がかかる。
計算時間が点の数の三乗に比例するんだったと。2-opt法は点の数の二乗に比例だったはず。
しかし、Or-opt法での改善効果はかなりあるので、外せなかった。380移動ぐらいなのを335移動ぐらいまで改善してくれるから。
もし、ここで四本の矢印を入れ替える4-opt法を導入すればさらに成績はよくなるだろうけど、
時間がかかって仕方ない。そんなわけでもうこの方法は限界であると。そう考えるわけだ。


焼きなまし法は、運悪く天保山を登ることにならないような工夫ですね。
焼きなましとは金属加工の技術の1つらしい。しかし金属加工など僕は詳しく知らない。
加工を行った金属の内部のひずみを取り除くために、その金属を熱してゆっくり冷やすことで結晶を再構築する技術。
ここでポイントなのは熱すること。熱するというのは金属をぐちゃぐちゃにすることでもある。
一旦ぐちゃぐちゃにしたものを、ゆっくり冷やして質のいい結晶を作ると。
熱すると言うことは質のいい結晶が出来ようとする一方で、質のよさそうな結晶がつぶれることでもある。
まぁしかし最終的にはきれいになればいいですねということです。
山登り法では改善される方向にしか作った近傍解への入れ替えを行わなかった。
しかし、この方法では改善される方向は必ず、そうじゃないときも一定の確率で入れ替えを行う。
一見悪くなるようだけど、実はそこから改善につながるかも知れない。そういう考えです。
その一定の割合をどんどん小さくしていって、十分小さくなったとき完成とそういうことです。
この確率だが、近傍解のコストと現在の解のコストの差、すなわち改悪量をΔと置くと、
e-(Δ/t) の確率でやるといいとされている。
delta<0 || myrnd.NextDouble()tは温度、もっとも現実の温度とは関係なくて、焼きなまし法が材料の温度を上げて、ゆっくり下げることに由来している。
ループ1回回るたびにtに一定量を掛けて、tを小さくしていく。これが十分小さくなれば終了と。
tが大きいほど、Δが小さいほど、確率は1に近づいて、悪い方向にも入れ替えされやすいと。


さて、この方法のいいところは何かというと、山登り法では行けなかった高いところに行けること。
山登り法では天保山に登るなら天保山にしか登れなかったが、
ところが少し悪い程度なら簡単に改悪されてしまう。
そんな風に改悪され続けて、生駒山に近づく方向に改悪された。すると生駒山に近づいた途端急激に登る。
まぁそんな感じで高い山にもたどり着けるのではないかということです。
ただ難しいのは温度をどれぐらい高くするか、温度をどのように下げるかということ。
もし目標がチョモランマならば、非常に高い温度で始めて、ゆっくり行かないと行けないだろう。
けど範囲が近畿に限定されていたらそんなに気合いを入れることはなくて、そこそこの温度で高速で冷やしてもいい。
まぁその辺の兼ね合いが難しいところです。


いろいろ調整してたが結果的には予想より遙か低い温度から始めて急激に下げていけばよかった。
まぁそんなわけでそこが難しい。ただ315移動程度と、山登り法では考えられなかったいい結果が出た。
なお、入れ替えを実行したときの改悪度の総和を求めて、それがこれまでの最小記録より小さくなったとき、
最小記録を変更して、最小の結果をメモする。
この方法、温度が小さくなればなるほど改悪される確率は減るけど、やはり改悪されます。
まぁそのあたりがあるので、今までのところもっともいい記録を残しておくと。そしてそれを答えにするようにした。
なお、山登り法で10回計算するよりは速い。
一応1回では悪い結果が出たとき困るので2回計算しているが、大体1回でも満足する結果が出てる。
それと、近傍解の作り方は、2-opt法のみで行った。
もともと、隣接した点の順序を入れ替えるだけでいいと思ってたが、
思ったよりよい方向に進まないので、前回の2-opt法のアルゴリズムを温度を変えながら何度もやることにした。
だから一回にかかる時間が長いですよ。前の計算を100回ぐらい繰り返してやるわけですから。
まぁOr-opt法がないだけましですけど。そう、Or-opt法なしでもいい結果が得られたわけです。
パラメーターの調整はもう少ししないといけないけど、まぁ今回のパラメーターは参考になるかと。
まぁこのあたりが難しいところでして、焼きなまし法は職人
技的な面があるんですよね。
点の数を変更して、どういうときどんなパラメーターが合うか調べてみたいとは思うけどね。

うーん、PHPなんだけどJavaにしか見えないよねー

最近Perlばっかりやってるじゃないかと、そうは思うのだけど、
だからといってWebプログラミングで使うのはPHPから変わらない。
まぁPHP自体、Perlと兄弟と言っていいほど似てるけど、
PHPはPerlのような過激な省略表現は通じないし、逆に厳格に事を運ぶことができる。
あと、文字列処理はPerlが、Webで役に立つ機能はPHPの方がそれぞれ優れています。
Perlのs/(foo+)/foo/g;、PHPの$_COOKIE[‘foo’]、どちらも変だけど扱いやすい。
PHPをコマンドラインで使えるからといって使う気にならないのは、コマンドラインでやりたいことは大方文字列処理だから。
逆はどうなんだという話だが、これはApacheにCGIの設定をするのがめんどくさいだけ。


実は、カウンター、クラスを使ったものに書き換えました。
べた書きだったものを、はがせる部分からクラスで表現することにした程度です。
その結果かなりスマートに見えます。
もともとそんなにごちゃごちゃしたプログラムでは無かったんだけどね。
実際どうしたかは省略するけど、まぁ見通しもいい。
PhpDocumentorを使って、Javadocのように、概要をHTMLに書き出してわかりやすくすることもできた。
C#のXMLDocumentationでもpublicなメソッド・プロパティには説明を付けるというルールでやってますからね。
このどうでもいいルールを守ることで非常に書きやすくなる。
ちなみにprivateの一部にも概要ぐらいは付けてることはある。けどあんまり意味ないしね。


さて、正直言うと、PHPのオブジェクト指向はJavaみたいだな。
どう考えても狙ってやってるとしか思えない。
ちなみにこのソースコードはコマンドラインでのテスト用のソース。まぁ考え方の確認のために作成してみた。
Windowsですが、なにげにPHPは入ってます。使い道はコマンドラインしかないですね。Apacheないし。

class person{
private $firstname,$familyname,$_age;
public function __construct($firstname,$familyname,$age){
$this->firstname=$firstname;
$this->familyname=$familyname;
$this->age=$age;
}
public function marge(person $other){
$other->familyname = $this->familyname;
}
public function __set($name,$value){
switch($name){
case 'age':
if($value<0) throw new Exception('Invalid age!');
$this->age = $value;
break;
default: throw new Exception('Field Not found!'); break;
}
}
public function __get($name){
switch($name){
case 'age': return $this->age; break;
case 'firstname': return $this->firstname; break;
case 'familyname': return $this->familyname; break;
default: throw new Exception('Field Not found!'); break;
}
}
public function __toString(){
return "$this->firstname $this->familyname($this->age)";
}
}

なんというか…PHPらしくもないソースコードですね。けどよく見ればPHPです。
アクセス修飾子は必須ではありません。省略すればpublicです。けど省略しませんよ。
PHPでは__(アンダースコア2つ)から始まるものは特別であるということだけど、
$_ageは特別ともいえないけど不気味な変数ということにしておいてください。
$firstname・$familynameは内部からは直接アクセスする変数、$_ageは内部からでもゲッター・セッター経由でアクセスするつもりの。
当然全部privateなので外部からアクセスはできません。
さて、それはともかく、コンストラクタは__constructです、昔はJava・C#のようにクラス名と同じ名前のメソッドだったんだけどね。
けど最近はこれらしいので、__constructを定義しました。
使うときは$p1=new person(‘Kenji’,’Kawaguchi’,20);のようにやります。こんなところもJava・C#と同じ。
Java・C#で言う、thisは、$thisです。もっともJava・C#では省略できるけど、PHPは省略不可能。
$foo->age=20; $foo->marge($bar);のようにこれも->でフィールド・メソッドを呼び出します。
非常にどうでもいいメソッドmargeを作ってみました。ここで引数リストを(person $other)のように型を付けているのはポイントです。
まぁ付けないのが普通だと思うけどね。けどこのように、このクラスのインスタンスという制限をかけることができる。
もちろんこの制限を付けなければ、偶然familynameというフィールド、または対応するセッターがあれば動くわけだから。
一長一短あるかと。
__setはセッターです。$p1->fooとして、public $foo;があればそれでいいんですが、アクセス出来ないときこれを呼び出します。
外部からは、どのフィールドでも、内部からでも$this->ageとしたら呼び出されますねぇ。
第一引数にフィールド名、第二引数にセットする値。
いろいろ考えたが、多分これがいいと思う。switchでフィールド名ごとに仕分けして、それぞれに書くと。
__getはゲッターで、これも同様の原理で動作し、第一引数にフィールド名。
ゲッターとセッターが分離されるのは気に食わんが、しかしこれで読み取り専用とか、値の制約とか簡単に実現できる。
throw new Exception(‘foo’);は例外を投げててるの。まぁ、これもJava・C#と一緒なのでなんというか…
__isset、__unsetは、アクセス出来ないフィールドに対応するisset、unsetの機能を、
__call、__callStaticは、どちらもアクセス出来ないメソッドを実行するやつ。ここまで来ると意味がわからん。
__toStringは等価な文字列を返す。これを定義すればecho “$p1\n”;のように扱えますよ。


まぁそんな具合でして、気合いをいれればかなり使い物になりますね。
なんせ、Javaに似ている、同時にC#に似ているというのはかなりありがたいことです。
ちなみに継承はclass runner extends person{ }のように行う。
抽象クラス・インターフェースなんかもあって、機能はやたら豊富。
まぁ好きなように使ってほしいということだろう。
PHPはオブジェクト指向を強要しないからね。けどそういう選択肢もあるよと。
まぁしかしながらかなり便利なので、これは今後活用していくよと、そういう風に思ったわけです。
最初に言った通り、ここで頭の整理のために、PhpDocumentorを使うことにしました。
これがどうもJavadocのパクリと言ってもいいような代物のようでして…
参考までにC#のXML Documentationについて、「DLLを身近に感じることができるクラスライブラリ」で取り上げています。
まぁ正直言うとこれとほとんど一緒。


さて、具体的な方法。
まずソースコードに特別なコメントを書き加える。

<?
/**
* オブジェクト指向を学習するインチキパッケージ
* @package foo
* @author Hidemaro ◆3rRY3LJ8tc
*/
$p1=new person('Kenji','Kawaguchi',20);
$p2=new person('Hanako','Tanaka',20);
$p1->marge($p2); echo "$p1\n$p2\n";
/**
* 人を表現するクラスです。
*/
class person{
private $firstname,$familyname,$_age;
/**
* コンストラクタです。氏名・年齢を登録します。
* @param string $firstname 名
* @param string $familyname 氏
* @param int $age 年齢
*/
public function __construct($firstname,$familyname,$age){ }
/**
* 等価な文字列を取得します。
* @return string 等価な文字列
*/
public function __toString(){ }

どうしてもかさばる…
/**~*/の間に書きます。**と2個あるのがポイントです。あと各行は*から始まる。
まずファイルの先頭にファイルについての概要を書く。
概要を1行程度で、そこから空行を開けて、長い説明を書くこともできる。
@authorとかは特別な意味をもつもの。@authorは作者、@packageはパッケージ名、適当につける。
クラスも同様。クラスの直前に書く。
フィールドについての記述法は省略。まぁフィールドを直接扱うことはないでということ。
メソッドは、これも直前に書く。まず概要を1行。必要なら空行を開けて詳しい説明を書く。
その後で引数・返り値の説明をする。
引数だが、@param string $familyname 氏のように書く、stringは型、$familynameは引数名、氏は説明。
ところでPHPの型だが、int,float,string,boolean,array(配列),resource(ファイルハンドルとか)が基本。
あとはobject、personなどのクラス名がある。しかしどの型でもいいときはある。そんなときはmixedと書くといいかな。
返り値は@return string 等価な文字列、のように型を書いて説明する。
これで基本的にOK、ただ難儀なのが__set,__get,__call,__callStaticで呼び出すことが前提の。
いろいろ議論されているようだが、まだ決まってないような気がするので、__set,__getの詳細部に書くことにした。


さて、書いたらどうするかというと、phpdocコマンドでHTMLに変換する。
pearでインストールします。pearはWindowsならばインストールしたディレクトリのgo-pear.batからインストール。

> pear install phpdocumentor

さて、これでインストール完了。
あとは非常に簡単です。

> phpdoc -t doc\ -d src\ -o HTML:Smarty:PHP
> phpdoc -t doc\ -f foo.php -o HTML:Smarty:PHP -q

-dでディレクトリ単位、-fでファイル単位で実行できる。
ディレクトリ内のPHPのソースコードと思われる拡張子のファイルを解釈する。
そして-t以下に結果のHTMLをはき出す。errors.htmlにエラーが書かれるので完了したら確認する。
-o HTML:Smarty:PHPはフォーマット。シンプルなフォーマットということらしいが、文字化けの問題が起きなくてラッキー。
詳しくは調べてください。他のでも文字コードをきちんと設定すればいいんです。
-qはあまりにうるさいから黙らせるために付けたオプション。
まぁこんな風に整理して入れておくと、後でわかりやすい。
それに、こういうルールでコメントを付けるとしておけば、作るときも楽だし、見たときもわかりやすい。
Perlにもperldocがあって、これも有名だけどね。まぁ調べてないだけ。
こういうクラスというのは誰がみてもわかるような工夫が欲しいと。
そういえばと思って、以前ダウンロードしたライブラリを見ると、docディレクトリがあるなぁ。
中身を見たらPHPDocumentorで作成されたHTMLだった。
ひたすら英語だし、専門用語が多くてわかりにくいけど、拾い読みできそうな気がする。
まぁこんな風に整理してあるのは大きそうです。

これがPerl式OOPなのかー

気になる記事があったので、Perlのオブジェクト指向を実践してみた。
まぁしかしながらPerlは型というのが非常に曖昧ですからねぇ。
JavaやC#ではよく使われるインターフェースなんてものは使わないでしょうねぇ。
まぁそんなわけで実行してみないとどうなるかはわからないということですが、
それが扱いやすさなのかも知れません。
PHPにもオブジェクト指向があるけど、こちらは結構強力なこともできるみたい。
こちらは機会があればやってみることにしよう。


しかし、Perlのオブジェクト指向は驚くほどひどい。
一体何がやりたいのだろうか…まぁしかしそんなこと言ってても仕方ない。

{
package person;
sub new {
my $pkg=shift;
return bless({@_},$pkg);
}
sub tostring{
my $self=shift;
return "$self->{first} $self->{family} ($self->{age})";
}
sub age{
my $self=shift;
if(@_){
$_[0]>0 or die;
$self->{age}=$_[0];
}
return $self->{age};
}
sub first{
my $self=shift;
$self->{first}=$_[0] if(@_);
return $self->{first};
}
sub family{
my $self=shift;
$self->{family}=$_[0] if(@_);
return $self->{family};
}
sub sum{
my $s=0;
$s+=$_ foreach(@_);
return $s;
}
BEGIN{
our $PI=\3.14159265358979323846264338327950288;
}
}

{ }で囲った中にpackage person;とする自体なんかおかしい。
package文が出てこないところは全部mainパッケージに所属。
このブロック内はpersonパッケージに所属。
パッケージはまぁJavaやらでいうクラスでしょうね。
わかりやすいように{ }で囲んだけど、実は{ }で囲わなくてもいいんだけどね。
package文が出てきてからそのブロック内で次にpackage文が出てくるまではそのパッケージだから。
まぁそれではなんかイメージがつかみにくいのでパッケージごとに{ }で囲んで中にpackage文を書くことにします。
さて、パッケージ自体はサブルーチンの名前の衝突防止のためにも使うありふれたものです。
最後に取っ手を付けたようにsumというサブルーチンを書いたけど
これを、&person::sumまたはperson::sumで呼び出すと。それが1つ。
ちなみに、$s+=$_ foreach(@_);はforeach(@_){ $s+=$_; }と意味は同じ。foreach修飾子は時々便利。
ライブラリなんかで、use Encode;とするとEncodeパッケージを読み込んで、Encode::decodeを単にdecodeで使えるようになるよね。
確かそうだったと思うのだけど、まぁそんな風にパッケージは使われていると。
まぁもともとファイルの先頭にpackage foo;のように書いたパッケージごとのファイルを作ってたというのが、
あの奇怪なpackage文の位置の理由にありそうな気がします。予想だけどね。
ちなみにBEGINブロックは、C#などで言う静的コンストラクタ、
ourはmyと違ってグローバル変数を宣言。use strict;のときは必須。
\3.14..は不思議だけど、リテラル(3.14とか’foo’とか)のリファレンスは読み取り専用の変数ということらしい。
こちらも$person::PIでアクセス出来る。もっともリファレンスだから$$person::PIとして使うだろうけど。
さて、しかしこれでは全くオブジェクト指向じゃない。まぁそこに無理にオブジェクト指向を押し込んだと言うことになるとおもうけど。


ルール1、newというコンストラクタ用のサブルーチンを定義、
第一引数にはパッケージ名を取って、bress関数を使ってインスタンスを作って返す。
newというサブルーチンがありますね。まず第一引数をshift(@_)の引数省略の、shiftで抜き取る。
そしてbress( {@_} , $pkg)という風に実行する。第一引数はハッシュのリファレンス、第二引数はパッケージ名。
実はPerlのオブジェクト指向では、メンバ変数は全部ハッシュのリファレンスに押し込むことになる。
{family=>’Yamada’,first=>’Taro’,age=>30}というように値を入れておくと。それをbressで引数に取ると。
コンストラクタは、$friend = person->new(family=>’Yamada’,first=>’Taro’,age=>30);のように実行するわけだ。
ところで、person::newではないのよね。まぁこういう特別ルールもあります。
そうすると、最初のshiftした後、@_には(‘family’,’Yamada’,’first’,’Taro’,’age’,30)が入ってる。
{ @_ }とすると、その引数の値ペアでハッシュのリファレンスが作られて、それを初期値にすると。
{@_}とすることは{‘family’,’Yamada’,’first’,’Taro’,’age’,30}、すなわち{‘family’=>’Yamada’,’first’=>’Taro’,’age’=>30}とするに等しいから。
{age=>0,@_}のように初期値を書いておく方法もある。同じことを二回以上書いたら最後のが優先。
まぁなんというか変な話です。わけがわからん。
bressした返り値は、そのパッケージ名を覚えただけで、ただのハッシュのリファレンス。
だから、$friend->{family}=’Kawaguchi’;または$$friend{‘family’}=’Kawaguchi’;という風に操作出来る。
しかし、これは基本的にはしてはいけない。まぁしかし変更できると言うことです。
このあたりがむちゃくちゃなことですよね。アクセス権というものはない。
まぁしかしながら基本的にはこういうことをしないのなら、C#でいうプロパティ、ゲッターとセッターを定義しないといけない。
それがage・first・familyの各サブルーチン。
ルール2、インスタンスメソッドを呼び出すときは$foo->bar(1,2)のように呼び出し、
そのサブルーチンの第一引数にそのインスタンス自身が入る。
$friend->age(20)のように実行することと、person::age($friend,20)とすることは何も変わらないということ。
C#でいう動的メソッドと静的メソッドの区別はないと、単に、第一引数にそのインスタンスを取るかどうか。
なので、だいたいそういうサブルーチンにはmy $self=shift;というのが決まり文句のように入ってる。
さて、セッター・ゲッターだが、引数なしならばゲッター、引数があればセッターとして動作するのが主流だとか。
これを簡単に実現するパッケージもあるそうだが、ここは堅実な方法で。


なんというか、役に立つような役に立たんようなというやつです。
しかしながら、ポリモーフィズムについては問題なく実現できている。
Perlは実行してみないと詳しい型はわからないという方針なので、ありがたいこともある。

my @objs=( car->new(name=>'Discovery',fuel=>30) , person->new(family=>'Yamada',first=>'Taro',age=>30) );
print $_->tostring(),"\n" foreach(@objs);

さっきのpersonというパッケージと、別にcarというパッケージを作った。
この2つのインスタンスを配列に入れて、foreachで回している。
そしてtostring()を呼び出してる。
けど、これはよく考えると、person::tostring($_)と、car::tostring($_)を使い分けてることになる。
まぁ当然これがオブジェクト指向のメリットだけど、同じ事をC#で実現しようとすると、そんなに単純でもない。
もっともToStringならObjectクラスのそれをoverrideすればいいけど、
もしこれがhogeメソッドだったらどうか、hogeメソッドを定義するというインターフェースを作って、それをいちいち実装しないといけない。
まぁしかし、Perlはそんなこと気にしない。まぁその点はありがたい点でもあります。
継承だが、これは随分むちゃくちゃ。@ISAとか
あと、もう1つの特徴のカプセル化ですが、そんなものないとしか思えない。
まぁそんな具合でして、便利なのかよくわからないけど、少なくともないよりかは選択肢が増えたと言うことですね。
それでいいのかもしれません。

テレビから生える赤耳・青耳

NHKというと日本どこでもテレビ・ラジオを放送しているわけで何かとありがたい。
衛星放送を使えば本当に全国どこでもニュースが見られますよ。
一応、NHK自体は誰でも見ることができるけれど、
受信装置を持つ人は受信料をNHKに払わないといけないので、
結果として受信料を払わなければいけない人はNHKを見ることができると。
まぁそれは問題ではないが、受信料を払わなければどうなるかはよくわからない。
その制裁のためか、衛星放送でCAS(限定受信システム)を使おうと考え、NHKはB-CASに出資したらしい。


ところで、B-CASというと、何のために作られたのかというと、
BS用のCAS(限定受信システム)を提供する会社として作られたと。
主に、WOWOWとスターチャンネルがそれぞれの契約者だけが受信できるようにするために使ってる。
だから民放を見るためにはもともと不要だったはず。
もっとも、WOWOWとスターチャンネルを見るには必須だから、対応してない受信機は困るけど。
NHKは現在はCASを使ってるわけじゃないけど警告テロップの表示をしている。
まぁこの程度でございまして、B-CASが問題になることはほとんど無かったと。
BSって難聴対策でもあるけど、贅沢品でもありますからね。いや、テレビ自体贅沢品だけど。
昔のBSアナログの時代、BSを使う人はそこまで多くなかったように思う。
今やBSデジタルは一般的に使われるようになりましたけどね。しかし、これは民放のおかげでしょうね。


まぁそれなら大した問題は無かったのだが、
実際デジタル放送を見ればわかるが、力士の毛穴が見えそうなぐらい画質がいい。
ストリームをそのまま制限無しにコピーされるのはさすがに困るという話になったらしい。
気合いを入れればDVDよりも高画質にできるからね。
まぁそんなわけで、制限信号を付加することと、その改ざん防止のためにストリームの暗号化をすることになったと。
その暗号化の道具にB-CASが使われることになったと。
それがBSデジタルと地上デジタルに適用されるようになったと。
そのためCASのために使われるあてのない、地上デジタル専用の青いB-CASが出ることになりました。
これまでは全部赤かったんだけどね。車載テレビなどは青いB-CASが付いてきてますね。
当初ストリームからのコピー1回、そのコピーからのムーブ1回というとんでもない制限だったけど、
最近ストリームからのコピー含めて10回のコピーと、最初のコピーからのムーブ1回に変わりましたね。
まぁこれなら、コンピュータに取り込んでの編集が出来ない以外は実用的と言えるのでは?
まぁしかし、B-CASを不正に読み取って、それで暗号解除だけしてしまうPC用チューナーとかありますけどね。
不正な根拠は、B-CASは添付された機器以外で使用することを規則で禁止していることですよ。
べつにセキュリティーホールを突いてるわけでもないはずなので。
生のストリームがコンピュータの中にあるのだから、コピーコントロールの効果など全くない。


まぁこんな具合でして、どうもこの調子でいくと、
テレビの受信装置を持つ人は、B-CASを持っていて、NHKの受信料も払うことになると。
そういう構図を見てると、B-CASをNHKの一部門にしてやれば、まぁ道理にはかなうかなと。
すべてのテレビ受信機器に組み込まなければいけない技術を独占している会社でして、
まぁ独占させる原因は全部の放送局が暗号化を始めたことなんですが、結果としてそうなってしまったと。
NHKは日本最大の放送事業者ですし、すでに受信を目的とする受信装置の情報は全部握ってるはず。
現状のB-CASのうさんくささに比べればかなりすっきりとした印象はありますよね。
しかし、B-CASの技術を使うのはWOWOWとか、関西テレビとか数あまたあるわけだ。
けどよく考えてみると、私的録音補償金の著作者への分配は一括してJASRACがやってるんだよね。
JASRACが日本最大の音楽著作権の管理団体だからだけど、
もちろんJASRACに著作権を信託していない人も、私的録音補償金を受け取るにはJASRACに言う必要がある。
まぁしかし、それで一応はうまくいってるんだよね。不思議な話だが。
奇怪な技術だからこそNHKが面倒を見るというのも1つありかなと。
横暴な話かも知れないけど、受信料を払わなければB-CASを発行しないこともできるし。


まぁ、元々のBS用のCASを提供するだけの会社なら何にも問題なかったんだよね。
それが幅をきかせるようになったのが何よりの問題だったわけで。
そりゃコピーコントロールの実効性を高めるためには暗号化がいいわけだけど、非常に息苦しいこともまた事実ですね。
海賊版対策のために導入されたはずだけど、引用とかに使うのも難しい。はて、どうしたものか。
しかしBSデジタル・110度CSでCASを提供するカードとしてはかなり便利な気がする。
今までのWOWOWのスクランブル解除装置重かったからね。
いい点も悪い点もあるけど、とりあえず暗号化するかしないかとか、無制限コピーを適用するべきか、
そのあたり放送する方が頭を働かせればまだ便利になるのでは。ニュース番組に暗号化・コピー制限はいらんし。