多段継承できるクラス生成関数を頑張って作りました

JavaScriptでクラスを作るのは簡単なのですが、継承したり、オーバーライドしたメソッドを簡単に呼び出すとなると途端にレベルが上がります。

  • ChromeFirefoxで使うので、関数呼び出し多めでも大丈夫(IE6でも動くけど)
  • this.parent.method()で親クラスのメソッド、this.parent.parent.method()で祖父クラスのメソッドが呼べる
    • this.parent.variableで親クラスのインスタンス変数とかはついていないです

という感じで、頑張って作ってみた。

使い方

var A = $_klass({
  init: function () { print("A init"); }, // コンストラクタ
  hoge: function () { print("A hoge"); },
  huga: function () { print("A huga"); },
  piyo: function () { print("A piyo"); }
});

var B = $_klass(A, {
//  init: function () { print("B init"); }, // コンストラクタは省略した時、親クラスを呼ぶ
  hoge: function () { print("B hoge"); },
//  huga: function () { print("B huga"); },
//  piyo: function () { print("B piyo"); }
});

var C = $_klass(B, {
  init: function () { print("C init"); },
  hoge: function () { print("C hoge"); },
//  huga: function () { print("C huga"); },
  piyo: function () { print("C piyo"); this.parent.piyo(); }
});

// インスタンスの生成
var a = new A; // A init
var b = new B; // A init
var c = new C; // C init

c.hoge(); // C hoge
c.huga(); // A huga
c.piyo(); // C piyo A piyo

ソース

function $_klass(parent, methods) {
	if (typeof parent === "object") {
		methods = parent;
		parent = null;
	}

	function klass() {
		this.klass = klass;
		if (klass.parent) {
			this.parent = makeParent(this, klass.parent);
		}
		this.init && this.init.apply(this, arguments);
	}
	klass.parent = parent;

	var kp = klass.fn = klass.prototype;

	if (parent) {
		var pp = parent.prototype;
		for (var i in pp) {
			var f = kp[i] = pp[i];
			if (typeof(f) === "function" && f.override) {
				kp[i] = (function (name) {
					return function f() {
						return this.parent(name, arguments);
					};
				})(i)
			}
		}
	}

	if (methods) for (var i in methods) {
		var t = kp[i], f = kp[i] = methods[i];
		if (typeof(f) === "function" && typeof(t) === "function") {
			f.override = true;
		}
	}

	return klass;

	function makeParent(self, parent) {
		var pp = parent.prototype, sp, tp;
		if (tp = parent.parent) sp = makeParent(self, tp);
		var fn = function (name, args) {
			var bk = self.parent;
			self.parent = sp;
			var rv = pp[name].apply(self, args || []);
			self.parent = bk;
			return rv;
		};
		for (var i in pp) if (typeof(pp[i]) === "function") {
			fn[i] = (function (name) {
				return function () { return self.parent(name, arguments); };
			})(i);
		}
		return fn;
	}
}

まとめ

  • for文でぶん回すわ、thisを束縛して関数作り直すわで、相当汚いので、誰か助けてください。
    • どうしてこうなった。

Firefoxの設定

結局、Firefoxも設定するオチ。

拡張

about:config

browser.backspace_action;0
greasemonkey.fileIsGreaseable;true
keyword.URL;http://www.google.co.jp/search?ie=UTF-8&oe=UTF-8&q=

VMWareのWindowsの初期設定

すべてのアップデートとVMWare Toolsの導入は完了しているものとする。

コントロールパネルより

  1. クラシック表示に切り替える
  2. 表示>ツールバー>ユーザー設定よりボタン名を表示しない、小さいアイコンを設定
  3. 表示>ステータスバーの表示
  4. VMWare Toolsより
    • 時刻を同期する
    • タスクバーに表示しない
  5. システムより
    • システムの復元の無効化
  6. タスクバーとスタートメニューより
    • ラシックスタートメニュー、プログラムをスクロールする
  7. フォルダオプションより
    • 適当に設定、すべてのフォルダに適用
  8. 画面より
  9. 管理ツール>サービスより
    • Security CenterとThemesの停止、無効化

ディレクトリと共有設定

  1. /home//win等共有したいディレクトリを作る。アクセス権は777とする(そうでないとWindowsからファイルを作ったりできない)。
  2. VM>Settingsより、Options>Shared FoldersをAlways enabled、Map as a network drive in Windows guestsにチェックを入れる。追加の名前はWindowsから参照されるディレクトリ名となる。
  3. \\.host\Shared FoldersをネットワークドライブでZ等を当てておく。
  4. マイドキュメントをZ:\win(上記で決めた名前)にする。

その他の設定

  • マイドキュメントを場合によってはC:\Homeにする
  • アプリケーションインストール用のディレクトリとして、C:\Applicationsを用意しておく

WindowsからUbuntuに移行するメモ(インストール編)

Let'snote CF-W7にLiveCDなど準備した上でインストールする。

Windowsでやっておくこと

  1. バックアップ忘れがないかの確認
  2. 音声がミュートになっていたら、解除しておくこと
    • やらないとどう修正しても音が鳴らない可能性が高い

CD起動を行う設定

  1. [F2]でBIOSの設定
  2. メイン>DVDドライブ電源をオン
  3. 起動の順序を適切に

インストール終了後は電池のもちを優先するため、オフに戻しておく。

インストール作業

CDからの読み込みにそこそこ時間がかかる。キーボードレイアウトはOADG 109Aで良いはず。すべての領域をUbuntuに与えてやって、あとは待つだけ。

WindowsからUbuntuに移行するメモ(準備編)

Let'snote CF-W7(メインマシン)をWindows XPからUbuntu 10.04に移行準備のためのメモです。

各種ディスクの準備

Ubuntu Desktop 日本語 Remixのダウンロード | Ubuntu Japanese Teamより日本語Remix CDイメージを入手して、CD-Rに焼きます。

また、Windows XPVMWareで動作させる予定であるので、こちらもディスクで準備しておきます。

データのバックアップ

外部のHDDにまるごとコピーして、後から使うのを探すのが基本方針ですが、データ破損を起こすと非常に困るデータもあるので、それは別途違うメディアでコピーできるようにしておきます。

WindowsホストのVMWareで動いているUbuntuゲストのデータ
  1. sshのキー
    • 個人的なことだが、最近パスワードを変えつつあるので、後でパスプレーズの変更をやってみる。
  2. zshの設定や履歴等
    • 特に履歴はUbuntuに慣れていない頃(現在)の試行錯誤の成果なので、保管しておく。
Firefoxの設定

profile全部コピーすれば良いような気もするけど、あんまり詳しくないので、個別に取ってインポートできるような体制にしておく。そもそも、Chromeに移行するつもりだから、個別に取った方がいい気もする。

  1. 導入したAddonの一覧と各種設定
  2. ブックマーク
  3. UserScript
    • Greasemonkeyのバックアップの時すると思うけど、自作のものが多数あり、忘れると困るため。
  4. 保存されているパスワード
    • アクセス先も忘れると困るので一括して、スクリーンキャプチャなどの方法で。
  5. プロキシ設定
アプリケーションのバックアップ

カスタマイズしすぎだったり、現在配布が中断している等、喪失すると困るアプリケーション。

  1. 萌ディタ
  2. FitzNOTE
    • 書いたテキストを独自方式ではない形にエクスポートしておく。
  3. MSNメッセンジャーSkypeFTPVPN
    • IDとパスワード等、各種設定のメモ
  4. JaneStyle
    • 巡回していたスレの一覧

なんかテキスト関連周りはずいぶん古いソフトを使っているような。

自作ファイルのうち、重要なもの

レポジトリで管理されていないものを取っておく。

  1. テキスト関連
    • 上記のアウトラインエディタで書いたもの全て。
  2. ソースコード関連
    • ウェブ関連はXAMPPを使っていたので、そこのディレクトリを必ず。
    • それ以外はそれぞれのプロジェクトのディレクトリを。
  3. 課題・研究関連
    • 無くしたら死ぬ。

まとめ

バックアップは一括で取るが、例外的に必ず取っておきたいものも個別に行う。今からCD-Rを買ってくる。

WindowsからUbuntuに移行するメモ(初期設定編)

Let'snote CF-W7にUbuntu10.04を導入してから、各種設定を行う。できる限りGUIでやっていく方向で。

無線LANとの接続

自宅は無線なので、無線のキーを入力してやれば、終了。

各種アップデート

  1. システム>システム管理>アップデート・マネージャで全部アップデートを行う。
  2. システム>システム管理>言語サポートでインストールを行う。

/home/下の日本語ディレクトリ名を英語に変更

LANG=C xdg-user-dirs-gtk-update

ディレクトリ名を英語にするか聞かれるので、Update Namesを選択。再ログイン後、ディレクトリ名を日本語にするか聞かれるので、次回から表示しないにチェックをいれ、古い名前のままにする

時刻をNTPサーバと同期するように設定

システム>システム管理>時刻と日付の設定より、設定をインターネット上のサーバと同期させるに変更。NTPサービスをインストールし、時刻サーバーをntp.nict.jp(自分で追加する必要あり)と設定する。

気温と天気の表示

右上の時刻表示をクリックし、場所を展開し、編集をクリックすると、時計の設定が表示される。場所は日本語で入力することで、サジェストが働く。

キーボードの設定

システム>設定>キーボードより、レイアウト>オプションを以下のように変更する。

  • Ctrlキーの位置を「Make CapsLock an additional Ctrl」
    • CapsLockもCtrlとして挙動する
  • Xサーバをkillするためのキーシーケンスを「Control+Alt+Backspace」

日本語環境セットアップ・ヘルパ

システム>システム管理>日本語環境セットアップ・ヘルパで以下のものを導入する。

  • otf-ipafont
  • ttf-umefont
  • ttf-konatu
  • lv
  • scim-anthy
  • scim-tegaki
  • tegaki-zinnia-japanese
  • flashplugin-installer
  • latex-env-ja
  • latex-extra-ja
  • jd
  • ttf-ipamonafont
  • lha-sjis
  • adobereader-jpn
  • adobereader-jpn-ipamonafont

Synapticパッケージ・マネージャ

システム>システム管理>Synapticパッケージ・マネージャで以下のものを導入する。

各ウェブサイトより導入するアプリケーション

zshの導入

which zsh
chsh -s /usr/bin/zsh # whichの情報を参照

VMWare Playerの導入

sudo sh VMWare-Player-*.*.*-*.*.bundle
メニューから消失した場合

システム>設定>メイン・メニューより、システムツールに新しいアイテムを追加。

アイコン
/usr/lib/vmware/share/pixmaps/vmware-player.png, /usr/share/icons/hicolor/48x48/app/vmware-player.png
種類
アプリケーション
名前
VMWare Player
コマンド
/usr/bin/vmplayer
コメント
仮想マシンの起動

などで作ればよい。

全てのサイトでGM_xmlHttpRequestを使うスクリプトその2

またか。(cf. 全てのサイトでGM_xmlHttpRequestを使うスクリプト

// ==UserScript==
// @name           GM_xmlhttpRequest
// @namespace      GM_xmlhttpRequest
// @include        *
// ==/UserScript==

var elem_send = document.createElement("div");
    elem_send.id = "_GM_xmlhttpRequest_send";
    elem_send.style.display = "none";
var elem_receive = document.createElement("div");
    elem_receive.id = "_GM_xmlhttpRequest_receive";
    elem_receive.style.display = "none";

document.body.appendChild(elem_send);
document.body.appendChild(elem_receive);

document.getElementById("_GM_xmlhttpRequest_send").addEventListener("DOMNodeInserted", function (evt) {
	var textarea = evt.target;
	var opt = JSON.parse(textarea.value);
	textarea.parentNode.removeChild(textarea);
	//if (opt.__api__ !== "p@$$w0rd") {
	//	return false;
	//}
	delete opt.__api__;
	var id = opt.__id__;
	["onload", "onerror", opt.__onreadystatechange__ ? "onreadystatechange" : ""].forEach(function (type) {
		if (type) opt[type] = function (req) {
			req.__id__ = id;
			req.__type__ = type;
			var textarea = document.createElement("textarea");
			    textarea.value = JSON.stringify(req);
			document.getElementById("_GM_xmlhttpRequest_receive").appendChild(textarea);
		};
	});
	setTimeout(function () {
		GM_xmlhttpRequest(opt);
	}, 0);
}, false);

location.href = "javascript:(" + function () {
	var count = 0,
	    cache = {};
	window.GM_xmlhttpRequest = function (opt) {
		opt.__onreadystatechange__ = !!opt.__onreadystatechange__;
		cache[opt.__id__ = ++count] = opt;
		var textarea = document.createElement("textarea");
		    textarea.value = JSON.stringify(opt);
		document.getElementById("_GM_xmlhttpRequest_send").appendChild(textarea);
	};
	document.getElementById("_GM_xmlhttpRequest_receive").addEventListener("DOMNodeInserted", function (evt) {
		var textarea = evt.target;
		var req = JSON.parse(textarea.value);
		textarea.parentNode.removeChild(textarea);
		var id = req.__id__,
		    type = req.__type__;
		delete req.__id__;
		delete req.__type__;
		var opt = cache[id];
		opt && opt[type] && opt[type](req);
		if (type === "onload" || type === "onerror") {
			delete cache[id];
		}
	}, false);
} + ")();void 0";

setIntervalでの監視をやめてみた。ちなみに自分はhttp://localhost/で使っております。そういう道具かなと。