ひしだまHPの更新履歴。 主にTRPGリプレイの元ネタ集、プログラミング技術メモと自作ソフト、好きなゲームや音楽です。
ひしだまの変更履歴
淡路島の電車の運行状況を取得する方法
なんか面白い話題があったので参入してみる(笑)
megascusさんの『「淡路島の電車の運行状況を聞いた話」をシステム開発に置き換えてみるはただの設計ミス』
僕は淡路島がget路線()メソッドを持っていても良いと思うんだよね。
淡路島クラスが地域インターフェースを持っているとして、地域インターフェースは以下の様になると考える。
public interface 地域 {
public 鉄道路線 get鉄道路線();
public バス路線 getバス路線();
public 航空路線 get航空路線();
public 船路線 get船路線();
}
この場合、地域によっては特定の路線が無いことも当然ありうるので、無いことを示す値(nullなりNullObjectなり)を仕様として決めて、呼び出す側がそれをチェックするのは当然だと思う。
ちなみにこれがScalaだと、(Scala初心者としては)以下の様にするかな。
trait 地域 {
def get鉄道路線() : Option[鉄道路線]
def getバス路線() : Option[バス路線]
def get航空路線() : Option[航空路線]
def get船路線() : Option[船路線]
}
val 運行状況 = new 淡路島().get鉄道路線().map(_.get運行状況())
→淡路島は鉄道が無いのでNoneが返る
で、地域インターフェースに各路線を全部入れるのではなく、個別のインターフェースを用意するとしたら、
public interface 鉄道路線 {
public 運行状況 get運行状況();
}
地域 t = new 淡路島();
運行状況 u = (t instanceof 鉄道路線) ? ((鉄道路線)t).get運行状況() : null;
ってするかなぁ。
ただ、こういうインターフェースを増やしていくのは、必要以上に煩雑になる感じがして嫌だな…。
ちなみに最近Eclipseプラグインの勉強をしているんだけど、Eclipseプラグインの場合はアダプターという仕組みを使うようになっている。
IAdaptable a = new 淡路島();
鉄道路線 r = (鉄道路線)a.getAdapter(鉄道路線.class);
運行状況 u = (r != null) ? r.get運行状況() : null;
ドラクエ10をやりながら10分くらいで書こうと思ったら、30分くらいかかった^^;
Eclipseプラグイン公開方法
開発したEclipseプラグインを公開する方法についてメモ。
Eclipseプラグインは「新規ソフトウェアのインストール」でインストールできるので、その為のダウンロードサイト(更新サイト)を用意すればよい。
更新サイトを作るためには、フィーチャー(プラグインのアーカイブのようなもの)を作る必要がある。
現在開発中のEclipseプラグイン(およびフィーチャープロジェクトや更新サイトプロジェクト)はgitで管理しているので、そのままGitHubにpushして更新サイトに出来れば楽。
GitHubのサービスのひとつであるGitHub Pagesを使うとそれが実現できる。
(GitHub Pagesの作成方法自体は簡単だったのだが、最初にサイトが表示されなくてハマったorz どうも、GitHubに登録したメールアドレスの認証(verify)が済んでいないとサイトが表示されないらしい。そんな事でハマっているのは自分くらいかも(苦笑))
で、これにより、試しに作っているAsakusa FrameworkのDMDLエディタープラグインを公開してみた。
自画自賛になるけど、DMDLのキーワードに色が付いているとなかなか良い感じ(笑)
たとえ半端な色の付き方をするバグがあってもね^^; (GitHubのIssuesも便利だなw)
DMDLエディター
Eclipseプラグインの開発の勉強として、Asakusa FrameworkのDMDLエディターを作ってみようと思ってやってみた。
TextEditorについては本にも載っているしXMLエディターのテンプレートで基本は出来るので、最初の準備はクラス自体は多めだけど、コピペしていけばいいだけ。
しかしまずコメントの色付けを行うに当たり、Damager/RepairerでDefaultDamagerRepairerとNonRuleBasedDamagerRepairerのどちらを使えばいいのか迷った。
ScannerもPartitionScannerと単なるScannerの二種類出てくるし、片方はTokenに文字列を指定するのに他方はTextAttributeで色を指定してるし。
色々ウェブサイトを見て調べた結果、エディター上のテキスト(ドキュメント)をまずパーティションに分割することが分かった。そして、パーティションの種類によってはさらにパーティション内を構文解析して複数のTokenに分かれる。
で、パーティションのTokenにはパーティション名を示す文字列を指定し、パーティション内部の一部分を表すTokenではTextAttributeで文字列のスタイル(色など)を指定する。
Damager/Repairerは、パーティション内部の構造がある場合はDefaultDamagerRepairerを使い、構造が無い場合(コメント等)はNonRuleBasedDamagerRepairerを使う。(ここでいうNonRuleというのは、「内部構造(構文解析ルール)が無い」という意味らしい)
TODO: 「/*」「*/」で囲まれたコメントの途中に文字列を追加したり削除したりした場合に色が変になることがあるorz
ここまで出来てしまえば、キーワードに色を付けたりするのは比較的簡単w
TODO: キーワードが単語の途中にあっても色が付いてしまうorz
あと、括弧「{」「}」にカーソルを当てたときに対応する括弧が強調表示される(灰色の四角で囲まれる)のも本を見たら簡単だったのでやってみた。
TODO: コメント内に括弧があった場合、そこが強調表示されてしまうorz
さて、ここから先もまだ色々作ってみたい仕様があるけど、これ以上はデータモデルの定義部分をちゃんと構文解析しないと駄目そう。
RuleBasedScannerを参考にすれば良さそうだという事は分かったんだけど、nextToken()でTokenを返していく形式で解析する方法が思い付かない…。
そもそも今までやったことがある構文解析って、四則演算のライブラリーくらいだからなぁ。これは解析結果をツリー状に蓄積していく方式だったので、ちょっと違うんだよなぁ。どうしたものか。
Eclipseプラグイン開発 コマンド
Eclipseプラグイン開発の基礎の勉強の続き。
マニフェストエディターの使い方とHello Worldの例のコマンド版のメモ。
依存プラグインの追加はマニフェストエディターで行うのが楽。
また、plugin.xmlへのextension(拡張ポイント)の追加は、当然plugin.xmlを直接テキストエディターで追加することで出来るが、マニフェストエディターで追加すると依存プラグインも追加してくれるような気がする。
Hello Worldのコマンド版は、テンプレートのひとつ。
最初はHello Worldのアクション版を試したんだけど、アクション版の方がextensionは1つで済む反面、実際に応用(メニューやツールバー・ショートカットキーの追加を)しようと思ったらコマンドを使う方が分かり易そう。
Eclipseプラグイン開発
明けましておめでとうございます。今年もよろしくお願いします。
今年の抱負〜みたいなものは好きじゃないので決めないけど(どんな新しいものが出てくるか分からないし、興味のあるものが出てきたらその都度試すんだし、予定なんか立たないよ)、年末年始の目標は立てていた。
1.ドラクエ10のバージョン1.2で追加された新職業の「スーパースター」でスティックスキルを100にする(メインは僧侶だからね!)。次に「魔法戦士」でHP+20を目指す。
2.Eclipseプラグインの作り方を勉強する。
1番目の目標は、スティックスキルは達成。魔法戦士は育成中。まぁこんなものでしょう。→現在のスキル構成
2番目の目標は、弊社のフェローから「そろそろEclipseのプラグインの作り方を覚えた方がいいんじゃないですか?」と言われたので、勉強しようと思ったもの。
以前ちょっとやろうとした事があるんだけど、その時は「Hello World」も出せずに挫折orz
今回は、薦められた『Eclipse 3.4 プラグイン開発 徹底攻略』をまず読んでみた。
なにせ実家には古いWindowsXPマシン(遅い・キーボード壊れかけ)しか無くて実質何も出来ないので、本を読むには最適の環境(爆)
(ちなみに新しいマシンを買った方がいいと思うんだけど、Windows8は操作感が変わりすぎるので勧められないし、Windows7でもリボンになったら両親には無理な気がする。この年齢層には「変わらない」「今まで出来たことがそのまま出来る」のが重要なんだけど、Microsoft(や家電メーカー)にはそういう考えは無さげ)
現在自分が使っているEclipseは3.7(たまに3.6)なので、3.4はちょっと古いんだけど、さすがにそうそう新しい本は無いらしい^^;
ただ、帰ってから実際に基礎的な部分を作ってみたけど、若干変わっている部分はあるけれども基本的には変わらないようだ。
(この本、何が出来るかはかなり網羅されていて素晴らしいんだけど、実際に写経しようとすると足りない部分がある(どこまでがテンプレートで生成されたものなのか分かりにくい)のが残念)
しかし、Eclipseプラグイン開発のテンプレートなんてものがあるのを初めて知った。
これを知ってれば、Hello Worldで挫折することは無かったはずだね^^;(でも本で説明を見なければ、何をやっているのかは分からなかったと思うけど)
どの例外を投げるべきか
Javaでどの例外を投げるようコーディングすべきかについてちょっと書いてみた。
言いたかった事は「NullPointerExceptionをスローするようなコーディングはするな」という事だけだったんだけど、体裁を整えていたら長くなってしまった^^;
(IllegalArgumentExceptionを知らない人は居ないと思うけど、IllegalStateExceptionとかは知らない人が居そうだし)
ついでに、例外の基礎のページに例外の概要を追加した。
初めてJavaの例外を勉強した頃(2003年)は、まずは使い方(文法)を調べるということで、とりあえず試した事を書いただけだった。
C++にもtry-catchがあるのは知ってたんだけど使い方はよく分からず、Javaで試してみて初めて理解したという感じだし(苦笑)
あの頃は例外に関する説明を書く知識なんて無かったからなぁ。9年近く経って、ようやく概要くらいは書けるようになったわけだ。
…進化が遅いな^^;(しかも間違ってたりして(爆))
pom.xmlの雛形
Mavenのpom.xmlの作り方(アーキタイプについて)をメモ。
pom.xmlの作り方がよく分からないーと言ったら、「最小限のJavaプロジェクトのアーキタイプがある」と教えてもらったので、試してみた。
やはり0から自習するより、知っている人から教えてもらってから試してみる方が進みが早い。
「mvn package」でビルドする(ファイルが生成される)のは知っていたが(ビルドという用語で合っているかどうかは知らないが^^;)、生成したファイルが「mvn install」でローカルリポジトリーに登録され、別プロジェクトのpom.xmlのdependencyに記述すれば登録したライブラリーを参照できる。
この仕組み自体は非常にシンプルで分かり易い。どのコマンドでそれが出来るのか分からなかっただけだな。
JavaFX2 TableView
JavaFX Scene Builderを1.0-beta42にバージョンアップしてみた。
自分がScene Builderを使い始めたときはbeta32だったが、メニューが日本語になったりパネルの種類が増減したり、色々変化している。
コントローラークラスを指定する場所が変わっていて、けっこう手間取った^^;
で、Table Viewを試してみた。
beta32ではTableViewに列を追加することが出来なかったが、beta42では出来るようになっていた。
なので、テーブル(表)にデータを表示するのはけっこう簡単に出来る。
ただ、実行時にユーザーがテーブルのセルを編集(値を変更)することは(簡単には)出来ないような気がする。もうちょっとバージョンアップを待たないと駄目かな?
そういえば、Scene Builderってまだ「Developer Preview」版なんだよね^^;
privateメンバーへアクセスする為のキャスト
kmizuさんのエラーの例の意味が最初分からなかった。
(lessThanというメソッド名なのに==で判定しているのがおかしいのかな?と思ったけど、そこは本題ではなかった)
cocoa_rutoさんのツイートで可視性に言及されていて、ようやく意味が分かった。
つまり、“自分を継承したサブクラス”として宣言した変数では、自分のprivateメンバーにアクセスできない。わざわざ自分自身にキャストしてやればアクセスできるようになる。
kmizuさんのソースでは、型TはFooを継承したサブクラスとなっている。(ジェネリクスのextends)
なので、Tの変数fooでは、FooのprivateメンバーであるaValueにアクセスできない(foo.aValueが不可視であり、コンパイルエラーになる)
うーん、こんな可視性の問題があったんだなぁ。Javaでもまだまだ知らない事が多い。
比喩でJavaのオブジェクト指向を説明してみる
オブジェクト指向の説明をするのに色々な比喩が用いられ(、実際のプログラミングと離れていて結局分かりにくいと批判され)ているが、敢えて例えてみたい。
例として、政党を考えてみる。(以下、政党名や変数名はてきとーに架空のものを使用)
まず、共通のものとして「政党」を定義する。Javaで書くとこんな感じ。
public interface 政党 {
public abstract 政策 政策を作成する();
}
「政策を作成する」というメソッドを持つインターフェースである。
インターフェースは「こういう処理を呼び出せる」というメソッド一覧を定義するもの。
実際の処理(ここでは「政策の中身」)は規定せず、「政党であれば政策を作成する機能を持つ」ということだけを定義している。
abstractは「抽象」と訳されている。実際の処理を書かないメソッドは抽象メソッドと呼ばれる。
(なお、インターフェースの抽象メソッドではabstractキーワードは省略することが出来る)
(抽象メソッドを持つクラスは抽象クラスと呼ばれる。インターフェースは特殊な抽象クラスとも言える)
このようにしておくと、例えば政策を実施する官僚クラスからは以下のような感じで政党から政策を取得することが出来る。
private class 官僚 {
public 結果 政策を実施する(政党 s) {
try {
政策 dummy = s.政策を作成する();
} catch(Exception e) {
}
return new 天下り先();
}
}
実体がどの政党であるかに関わらず、メソッドを呼び出すように記述できる。これがオブジェクト指向(インターフェースを用いたプログラミング)の優れた点である。
なお、try〜catchは例外(正常な結果でない出来事)が起きたときにそれを受け止めて何らかの処理を行う為のもの。今回はcatch句に何も書いていないが、こういうのは「例外を握り潰す」と言われ、良くないコーディングの典型である。(例外は「都合の悪い事」ではなく「発生しうる事」なので、それに応じた処理を行う必要がある。少なくとも、ログ出力などを行い、外部の人(運用者)に見えるようにすべきである)
そして、実際の個々の政党クラスは“政党インターフェース”を実装することになる。「実装」とは、具体的な処理を記述することである。
(具体的に処理が書かれているクラスを、(抽象クラスに対して)具象(ぐしょう)クラスと呼ぶ)
例えば「自分が良ければ他人や将来の世代のことなんかどうでもいい党(以下、自党)」や「共に生産性を上げようなどと人類には不可能なことを言う党(以下、共党)」は以下のように書ける。
public class 自党 implements 政党 {
@Override
public 政策 政策を作成する() {
return new 我田引鉄();
}
}
public class 共党 implements 政党 {
@Override
public 政策 政策を作成する() {
return new 実現不可能な理想論();
}
}
継承元クラスに存在するメソッドに自分の処理を記述することを「オーバーライド(上書き)する」と言う。オーバーライドされたメソッドには@Overrideというアノテーションを付ける。
クラスの定義は、処理内容が記述されているだけであり、プログラム内で使う際には「インスタンス」を作る必要がある。インスタンスとは、いわば「処理を行う“中の人”」である。
インスタンスは「new」を使って作成する。以下の様になる。
政党 元祖自党 = new 自党();
政党 亀下新党 = new 自党();
政党 石井新党 = new 自党();
政党 橋原新党 = new 自党();
これらは、インスタンス(中の人)は違うが、クラスは同じなので実施する処理内容も全く同じである。
なお、変数の宣言は、実際のクラス名でなく、インターフェース名ですべき。そうすれば、後からnewするクラスをとっかえひっかえしても後続のプログラムは影響を受けない。
既存のクラスを継承して新しいクラスを作ることも出来る。
例えば、自党を継承した「民の為と称して好き勝手やる党(以下、民党)」は以下の様になる。
public class 民党 extends 自党 {
}
継承元と処理が同じ場合は、特に処理(メソッド)を書く必要は無い。
政党 小沢自党 = new 民党();
他の具象クラスを直接継承(extends)するのではなく、別インスタンスのメソッドを呼び出すような構造も作れる。
こういう仕組みを「委譲」と言う。
public class 委譲政党 extends 政党 {
protected 政党 s;
public 委譲政党(政党 s) { //コンストラクター
this.s = s;
}
@Override
public 政策 政策を作成する() {
return s.政策を作成する(); //他の政党に委譲する(他の政党の政策をそのまま使う)
}
}
コンストラクターは、インスタンスを作る際に引数を受け取ったりそのクラス独自の初期化を行ったりするもの。
コンストラクターで引数を受け取ってフィールド(クラス内で共通に使える変数)に保持するのは常套手段。
フィールド(「フィールド変数」という呼び方は間違い)とローカル変数で同じ変数名を使うことが出来る。同じ場所で使う場合、区別できるよう、フィールドには「this.」を付ける。
(同じ名前を付けることによって別変数にアクセスできなくなることをシャドーイングと言う)
引数つきのコンストラクターを使ってインスタンスを作る場合は、newするときに引数を渡す必要がある。
政党 公党 = new 委譲政党(元祖自党);
政党 社党 = new 委譲政党(元祖自党);
全然関係ないですが、つい最近、虚構新聞に釣られる人が出て話題になってましたね。
自分も虚構新聞には何度か騙されて^^;楽しませていただいていますがw、情報が正しいのか、どういう意図で書かれているのか・信じるのかは読み手が汲み取れるようにならないといけませんね。騙そうとする人(宗教や新聞テレビのプロパガンダ等)は、「嘘」と書かずに嘘をついたり誘導したりするので。(虚構新聞は虚構と書いてくれているので良心的w)
それがネットリテラシー、いやネットに限らずリテラシーとして必要なんでしょう、現代人には。
騙す方が悪いとは思いますが、犯罪者に倫理観を求めるのは不可能なので。
| « 前ページ |

