yamicha.com's Blog - Presented by yamicha.com
Blog yamicha.com's Blog - 2018/06 の記事
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]

yamicha.com's Blog
 諸事情により、現在更新休止中。ご了承ください。もし今後ブログを再開することがあるとすれば、その際にはこのブログスクリプトではなく、新しく開発したものによるかもしれません。
 当ブログ管理者についてはこちらをご参照。
開発魔法(737)
社会問題(733)
お知らせ(11)
質問・バトン回答(15)
ゲスト出演(8)
経済・知的財産(150)
ゲーム開発(182)
[Ada] 勝手に補足
- Note
- 金配りの次の一手


- Endless Ultimate Diary
- 銃世界

漢字バトン
- うるる雑記帳
- 漢字接力棒

ツキアイゲノムバトン
- ブログ@うにうに画像倉庫
- あぶ内閣

縺イ縺セ縺、縺カ縺励ヰ繝医Φ
- 月夜のボヤキ
- 騎士サーラバトン
パスワードを使う
名無し (2012/02/27)


開発者解放裁判
yamicha.com (2010/03/14)
Winnyに関しては、私も「純白」とまでは考えておりませんし、使用し..

開発者解放裁判
通りすがり (2010/03/08)
winnyに関しては「ダウンロードソフト板」なんてところを拠点に開発..

新型インフルエンザの恐怖
いげ太 (2009/11/03)
> C#などの「int Some(int , int)」は、F#では「(int * int) ->..

時効に関する思考
yamicha.com (2009/08/31)
>いげ太さんコメントありがとうございます。手元にドキュメントが少..
Homepage
Blog Top
Normal View
List View
Search
Calendar
Comment List
Trackback List
Blog RSS
Send Trackback
Phone Mode
Administrator
yamicha.com
Blog
るううるる。
Source
法令データ提供システム
FindLaw
Development
Java2 Platform SE 6
Java EE 6 API
MySQL Developer Zone
PHP Reference
MSDN Library
Ada Reference Manual
Objective Caml
Python Documentation
Erlang
Prolog Documents
 垂オ訳ございませんが、現在このブログではトラックバックを受け入れていません。

 この記事に対してリンクされる場合には、こちらのURLをご利用ください。
http://void.yamicha.com/blog/blog.cgi?mode=view&number=321
 上記URLをトリプルクリックされますと、簡単にURL全体の選択が行えます。

※以下の記事がトラックバックされます。
背筋も凍るお話
2006/03/15(Wed)17:24:32
 先日やりかけになっていた「XPath for Java」。クラス「javax.xml.xpath.XPath」を用いることで、JavaではXPathを使うことができるのですが、これはネームスペースがなければの話であって、ネームスペースを使用する場合はXPathを使うことができません(ちなみにJavaのXMLパーサはデフォルトではネームスペースを無視します。無視させないためには、ファクトリを設定してからDOMオブジェクトを作らねばなりません)。
 ただ、これは正確には「ネームスペースを使うにはインタフェースNamespaceContextを継承したクラスをXPathに渡さなければならないが、J2SE 5.0にこのインタフェースを実装していたり、またはファクトリとなるようなクラスはない」が正解です。もしかしたらApplication Serverにはあるかもしれませんが、少なくともJ2SE本体にはありません。つまり、継承したクラスを自分で作りさえすればネームスペースを使うことはできることになります。
 しかしまあ、このインタフェースの規則のややこしさといったら。ネームスペースURIの正引き・逆引きに対応しなければならないばかりか、W3Cの特定のURIを渡されたら特定のプレフィックスを返したり、逆にそのプレフィックスを渡されたら特定のURIを返したり、getNamespaceURIでは空白を渡されたらデフォルトネームスペースURIを返す必要があるくせに、getPrefixではnullであったりと。
 ところで、このインタフェースにはIteratorを返さなければならないメソッド(getPrefixes)が含まれているのですが、Iteratorはジェネリックスを使っています。それ自体は別に構わないのですが、バグだか仕様だか知りませんが(少なくともTomcat 5.5では)JSP内でジェネリックスのあるクラスを返り値に使うとどういうわけか「非互換」エラーを起こします。色々やってみましたが、今のところ回避できないのが実状です。
 仕方がないのでServletを使って実装しました。これならしっかりコンパイルも通りますし、正しく動作させることができます。しかし、JSPなら作成も検証も楽ですから、できればJSPを使いたかったのですが。便利で不便なジェネリックス。
class Namespace implements NamespaceContext{
	String prefix[];
	String regns[];
	int len;
	public Namespace(){
		len = 0;
		prefix = new String[len];
		regns = new String[len];
	}
	// PHP風に registerNamespace で登録します
	// 引数の順番もPHPにあわせてみました
	// registerNamespace("" , "[URI]") でデフォルトも指定できるはず
	public void registerNamespace(String p , String ns){
		String np[] = new String[len + 1];
		String nns[] = new String[len + 1];
		for(int i = 0; i < len; i++){
			np[i] = prefix[i];
			nns[i] = regns[i];
		}
		np[len] = p;
		nns[len] = ns;

		len ++;

		prefix = np;
		regns = nns;
	}
	// Prefix -> NamespaceURI
	public String getNamespaceURI(String p){
		// xml -> http://www.w3.org/XML/1998/namespace
		if(p.equals(XMLConstants.XML_NS_PREFIX))
			return XMLConstants.XML_NS_URI;
		// xmlns -> http://www.w3.org/2000/xmlns/
		if(p.equals(XMLConstants.XMLNS_ATTRIBUTE))
			return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;

		// 当該ネームスペースを探す
		for(int i = 0; i < len; i++){
			if(p.equals(prefix[i])){
				return regns[i];
			}
		}

		// DEFAULT_NS_PREFIX の場合でデフォルトが登録されていない
		// または登録されていないPrefixが検索された場合
		return XMLConstants.NULL_NS_URI;
	}
	// NamespaceURI -> Prefix
	public String getPrefix(String ns){
		// http://www.w3.org/XML/1998/namespace -> xml
		if(ns.equals(XMLConstants.XML_NS_URI))
			return XMLConstants.XML_NS_PREFIX;
		// http://www.w3.org/2000/xmlns/ -> xmlns
		if(ns.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI))
			return XMLConstants.XMLNS_ATTRIBUTE;

		// プレフィックスを探す
		for(int i = 0; i < len; i++){
			if(ns.equals(regns[i])){
				return prefix[i];
			}
		}

		// 見つからない場合
		return null;
	}
	// 特定URIに対応する全プレフィックスを返す
	public Iterator getPrefixes(String ns){
		Vector<String> v = new Vector<String>();

		if(ns.equals(XMLConstants.XML_NS_URI)){
			v.add(XMLConstants.XML_NS_PREFIX);
			return v.iterator();
		}
		if(ns.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)){
			v.add(XMLConstants.XMLNS_ATTRIBUTE);
			return v.iterator();
		}

		for(int i = 0; i < len; i++){
			if(ns.equals(regns[i])){
				v.add(prefix[i]);
			}
		}
		return v.iterator();
	}
}
 本当はHashtable辺りを使おうかと考えていたのですが、そもそもURIとプレフィックスのどちらをキーにすべきかすら不明ですし、XMLでは1つのURIまたはプレフィックスが複数のプレフィックスまたはURIを持つことがあり、キーと値の対応するHashtableでは限界があると考え、あえてString配列を使いました。スマートではありませんが。本当はnullを渡されたら「IllegalArgumentException」を投げなければならないのですが、割愛。
 で、使用方法ですが、以前に作ったXML(アビリティリスト)を流用して試してみます。
// ファクトリを準備
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

// 重要 : ネームスペースを有効にする
dbf.setNamespaceAware(true);

DocumentBuilder db = dbf.newDocumentBuilder();

// XMLデータを読み込み
Document d = db.parse("webapps\\ROOT\\ns.xml");

// ファクトリからXPathを取得
XPath xp = XPathFactory.newInstance().newXPath();

// ネームスペースを作る
Namespace ns = new Namespace();
// なんともPHPライクな登録方法
ns.registerNamespace("ilias" , "http://www.yamicha.com/ilias");
ns.registerNamespace("sara" , "http://www.yamicha.com/sara");
xp.setNamespaceContext(ns);

// 魔道士イリアスのアビリティの中でMR消費の値を返す
NodeList n = (NodeList)xp.evaluate("//Base/ilias:Ability/@ilias:use" 
	, d , XPathConstants.NODESET);
out.println("該当個数 : " + n.getLength());
for(int i = 0; i < n.getLength(); i++)
	out.println(n.item(i));

// 同じく魔道士イリアスのアビリティの中でLA消費の値を返す
n = (NodeList)xp.evaluate("//Base/ilias:Ability/@sara:use" , 
	d , XPathConstants.NODESET);
out.println("該当個数 : " + n.getLength());
for(int i = 0; i < n.getLength(); i++)
	out.println(n.item(i));
 これを実行すると、以下のような結果が得られます。
該当個数 : 3
ilias:use="108"
ilias:use="86"
ilias:use="126"
該当個数 : 1
sara:use="200"
 どうやら正しく動作しているようです。めでたし。
 ところで、J2SE 5.0ではこれまで扱ったアノテーション、ジェネリックスなどの他、foreachループもサポートしています。無論、知らなかったわけでも力量が足りなかったわけでもなく、利点もなく面倒だから扱わなかったに過ぎません。せっかくですから扱ってみます。
 foreachといってもPerlやPHPのようにforeach文が用意されているわけではなく、forループを簡素化しただけです。配列は最初から、クラスに関してはインタフェースiterableを実装したものに関しては同様にforeachループを用いることができます。その意味で、foreachループには2種類あることになります。
 ただ、「使うことに意義がある」とさえいえる、PerlやPHPの非常に有用なforeachとは違い、Javaのforeachは単にコンパイラが「従来までのループ」と「新しいforeachループ」の2つの書き方をサポートしたに過ぎません。ですから、配列の値を取り出した上にインデックス数と一緒に表示したいような場合は、従来のforを使った方がよっぽど楽です。
 というわけで作ってみた配列版foreachです。
String names[] = 
	{"サーラ" , "サラサーラ" , "サラサラサーラ" , "(サラ){4}サーラ"};

for(String name : names){
	System.out.println(name);
}

// これまでの書き方なら
for(int i = 0; i < names.length; i++){
	System.out.println(names[i]);
}
 別にそんなに代わり映えするものでもなし。後者の方がJavaっぽいですし(どういう理由だか)、何より後者の方法さえ使っていれば、5.0以前のJavaでも正しくコンパイルすることができます。手間が激減するのであればともかく、互換性を考えれば、わざわざforeachループを使うまでもないでしょう。
 もう1つ、忘れてはいけないのがクラス版foreachループです。結局のところIteratorを順番に取り出してループしているだけであって、そこまですごいものではありません。
// foreachに対応したクラスを作る
class ForLoop<T> implements Iterable<T>{
	T values[];
	int len;
	public ForLoop(T val[]){
		values = val;
	}
	public Iterator<T> iterator(){
		ArrayList<T> al = new ArrayList<T>();
		for(T value : values)
			al.add(value);

		return al.iterator();
	}
}

// 使い方
// ジェネリックスなので何型でも渡せるが、とりあえず先ほどのデータ(String)を
String names[] = 
	{"サーラ" , "サラサーラ" , "サラサラサーラ" , "(サラ){4}サーラ"};

ForLoop<String> fls = new ForLoop<String>(names);
for(String fl : fls){
	System.out.println(fl);
}
 どちらも結果は同じです。ForLoopクラス内でも、さりげなくジェネリックスと配列foreachを活用しているのが私らしいところ。キャストなどという無粋なマネはしません。
 さて次、PostgreSQLではトリガでストアド プロシージャを呼んだりするらしいですが、MySQLでは実装中とのこと。とはいえ、これこそ「やればできる」というものでして。やってできないことはない、とはいえMyISAMでトランザクションを使ったりすることは絶対に無理ですが、ストアド プロシージャを呼ぶ程度なら何とか。
// 更新時刻格納テーブル
CREATE TABLE updatetime(name VARCHAR(256) , dates DATETIME , INDEX(name));

// トリガを設定するテーブル
CREATE TABLE trigsample(number INT , name VARCHAR(32) , PRIMARY KEY(number));

DELIMITER //

// 時刻を記録するプロシージャ
CREATE PROCEDURE updateprocedure(IN name VARCHAR(256)) 
BEGIN 
 INSERT INTO updatetime VALUES(name , NOW());
END;//

// そのプロシージャを呼び出すトリガ
CREATE TRIGGER updatetrigger AFTER INSERT ON trigsample FOR EACH ROW 
BEGIN 
 CALL updateprocedure('trigsample');
END;//

DELIMITER ;

INSERT INTO trigsample VALUES(0 , 'Dual Knight') , (1 , 'Sword Master');

SELECT * FROM updatetime;

// Result
name	dates
trigsample	2006-03-15 15:03:06
trigsample	2006-03-15 15:03:06
 これで結構何とかなってしまいます。なお、トリガでトランザクションを使うことはできないようです。ストアド内ならできるにもかかわらず。ストアド ルーチンでは「BEGIN」のワードが使えないため、「START TRANSACTION」します。
DELIMITER //

CREATE PROCEDURE transactprocedure() 
BEGIN 
 START TRANSACTION;
  SELECT * FROM sample FOR UPDATE;
  INSERT INTO sample VALUES(128 , yamicha.com');
 ROLLBACK;
END;//
 こういうのを普通にコールすれば正しく動くのですが、トリガで呼び出すとエラーになります。大体MySQLではトランザクションをネストできませんから、トリガがトランザクション内で実行されていたら色々面倒なことになるのでしょう。

 またも笑い話、東京教育委員会が国旗国歌を厳しく強制しています。生徒の起立なしなら教師の処分もあるとか。教師を脅して生徒の行動を強制させようという魂胆ですが、私が生徒ならまず100%起立しません。教師・先生は数あれど、私の恩師は自動車学校の2名の教官と学科教官以外には1人たりとも存在しません。残念なのは、私が生徒でないことですが。
 私は法案の起こりからして国旗国歌法案に強く反対しています。以前、国旗国歌に関する圧力によって校長が自殺したことがありました。これを受けて政府が同法案を出したのですが、見出しだけを見た時の私の感想は「ああ、やっぱり」でした。もう2度とこのような悲劇を繰り返してはいけないのですから。
 ところが、記事内容を読んでビックリ。私はてっきり「国旗国歌強制で死人が出たのだから、これからは学校の裁量にしよう」という法案を想像していたのですが、何と正反対。もうあきれ果てて物も言えませんでした。何というサル知恵。それ以来、私は「国旗国歌法案絶対反対」を貫いています。国旗国歌の理念はこの際どうでもよろしいですし、そんな偉そうな能書きなどいちいち気にしているほど余裕も暇もありませんが、こういう法律の作り方だけは許せません。
 さて、ここで(寒さが戻ってきただけに)納涼怖い話を1つ。いよいよもって鳥インフルエンザ発生の可能性が高くなっています。WHOも会合を開いたりと色々活動を行っているようで、かなり危険が強くなっていると考えて良いでしょう。SARSのように立ち消えになってくれるのが最も良いのですが。
 ウィルスというのは非常に変異しやすいものですから、条件さえ重なればあっという間に人間に感染するようになるでしょう。感染力がどの程度かは実際に変異ウィルスが出てこないことには分からないのですが、人間が新ウィルスに対する免疫を持っていない以上、感染すると高い確率で発病することになります。
 そして、このウィルスの何が怖いって、免疫の自己攻撃を誘発する点でしょう。普通のインフルエンザの場合、大流行が起きるとお年寄りや乳幼児などを中心に重篤化・死亡例が出たりしますが、鳥インフルエンザが怖いのは年齢に関係なく高い致死率を持つ点であり、これの原因が「免疫による自己攻撃」とされています。抵抗力が高ければ安全とは言い切れません。
 はっきり言って病原体は人類を存亡の危機に追いやるほど恐ろしいもので、それこそイラクくんだりに時間と人員と資金を浪費している場合ではありません。まだ人対人のウィルスでない鳥インフルエンザがこれだけ騒がれていることを見ても明らかです。もともと血液型が色々あること自体、例えば特定の血液型への致死率が高い病気が流行したような場合、人類が存続する可能性を高めるためといわれていますから。
 普通のインフルエンザにしても、日本ではバカのようにタミフルを乱用していますが、タミフル耐性インフルエンザはきっとすでに存在します。タミフルなど飲まなくていい人間が贅沢病でタミフルを飲むから、その結果としてインフルエンザを強化させ、それが老人や病人などタミフルなくしては生命の存続すら危うい人に感染したりするのです。窓から飛び降りるなどの副作用の可能性がある事例を考えても、飲まなければ生命などが脅かされる場合を除き、私はタミフルを飲むことは避けたいです。
 ついでに言っておけば、ウィルスは遺伝子を交換して性質を変えたりするそうですが、鳥インフルエンザがタミフル耐性インフルエンザの遺伝子をもらったらどうしますか。日本の「何ら問題なく治癒する病気に対して薬を乱用する」という贅沢病、下手すると人類の敵になる可能性があります。
 怖いのはインフルエンザばかりではなく、生物兵器に天然痘が用いられたら、といった試算もあります。それならまだかわいいもので、抗生物質耐性結核が流行し始めたら手に負えません。薬があるから結核は簡単に治癒するのであって、これに耐性を持たれて手も足もでなくなってしまえば、結核は死病に逆戻りです。
 結核は菌が起こす病気ですが、これの治療方法としては、2種類またはそれ以上の薬をしばらくの間毎日飲むのが標準的なのだそうです。しかし、薬をいい加減に飲んでいると薬に耐性ができてしまうとのこと。細菌でさえこの調子なのですから、もともと変異しやすい性質を持つウィルスならどうなることか。
 ついでに異常プリオンも恐ろしいこともお忘れなく。「遺伝子のない病原体」などといわれますが、本当に遺伝情報がないのか、それならどうして病原性を持つのか、といったことは未だはっきりとは解明されていません。仮に異常プリオンが遺伝情報を隠し持っており、何らかの方法で人から人に感染するようなことがあれば、それこそどうなるか。
 病気というのは恐ろしいです、ホント。事件の事故のと毎日大騒ぎですが、死者数で見れば病気が最も高いのですから。

 ところで、何の因果か変な夢を見ました。何やら「Typing Wind 2」というものがあり、それをプレイしている夢です。はっきり言ってタイピング系のプログラムは現在まで企画案にすら入っていませんでしたが、少しばかり変な気分です。
 内容としては、夢だけに夢と消えてしまったのですが、まあタイピングです。しかし、戦略タイピングとでも名づけましょうか、タイピングの速さと戦略で戦うようなゲームでした。夢では魔道士イリアスか誰かが戦っていました。片方がイマイチでももう片方である程度カバーできるわけです。ある意味私らしいゲームですが、せっかくならソースまで見せてくれればよかったものを
 そこで考えたのが、例えば単語をタイプしたら速度に応じてMRが蓄積し、それを使って攻撃などの行動ができる、といったゲームですが、あまり面白そうではありません。com.yamicha.romanxのパッケージを使えば作れるのですが、おぼろげには見えているものの骨組みが全く決まらず、実装に入れないためもやもやした企画がこれで3、4個。
 さて、どうしたものでしょう。しかもSQLもXMLもちょくちょくやらなければ知識が失われてしまいますし。難しいところです。
カテゴリ [開発魔法][社会問題][ゲーム開発] [トラックバック 0][コメント 0]
<- 前の記事を参照 次の記事を参照 ->

- Blog by yamicha.com -