Perlにおける空リファレンスの真偽判定について

弾さんのブログにも紹介されている通り、空リファレンスをif文で評価すると真になるようだ。
気を付けないとハマりそう。

http://blog.livedoor.jp/dankogai/archives/51220619.html

なお、空リファレンスのときに偽とみなしたいときはデリファレンスした値をif文に入れると良い。

Mingにおける深度の扱い

PerlにはMingというライブラリがあり、プログラムでSWFムービーを生成することができる。
Mingで生成したSWFのシンボルには深度を設定することができるが、設定方法には2通りある。
1. setDepthメソッドを使う

my $movie = new SWF::Movie();
my $mc = new SWF::MovieClip();
my $handle = $movie->add($mc);
$handle->setDepth(100);

2. ActionScript内でduplicateClipしたときに設定する

clip = /mc;
name = 'hoge';
depth = 100;
duplicateClip(clip, name, depth)

1と2では双方ともに深度として100を指定しているが、setDepthメソッドとduplicateClipでは深度の扱われ方が違う。
duplicateClipで指定できる深度の幅は-16384から1048575となっており、setDepth(0)はduplicateClip(clip, name, -16384)と等しくなる。つまり、setDepth(16384)と指定した深度とduplicateClip(clip, name, 0)が等しくなる。
そのため、setDepthで深度を指定する場合はオフセット値として常に16384を足すと良い。こうすることでsetDepthするときとduplicateClipするときで深度の違いを意識しなくて済む。

参考URL
http://help.adobe.com/ja_JP/FlashLite/2.0_FlashLiteAPIReference2/WS5b3ccc516d4fbf351e63e3d118ccf9c47f-7ff2.html

Perlの演算子の優先順位

下記の様に、notと&&を混ぜて使うときは、演算子の優先順位に気を付けなければならない。

my $a = +{};
my $b = 0;

print "hoge" if not exists $a->{foo} && $b; # hogeが出力される!!

上記の例だと、not exists $a->{foo}よりも先にexists $a->{foo} && $b が評価されてしまうので、if文全体としては真になってしまう。
exists $a->{foo} && $b は、0 && 1となり、偽と判定されるが、この結果に対してnotを適用するので、全体としては真になるのだ。こういうときは丸括弧を使うか、!を使うのが良い。

my $a = +{};
my $b = 0;

print "hoge" if (not exists $a->{foo}) && $b; # hogeは出力されない

のように書けばOK。

Vimで検索語のハイライトを消す方法

Vimで / コマンドで検索すると、検索結果がハイライトされるが、そのハイライトが原因でソースコードが見にくくなったりするので、ハイライトを消したいときがある。その時は

:noh

でOK。

ckw + nyaos環境の構築と,右クリックメニューから,ckwを対象のフォルダに移動して開く方法について

いい加減,Windows標準のコマンドプロンプトに嫌気が(特に履歴を保存できない点に)差してきたので,他のコンソールを探してみました.どうやら,ckwというコマンドプロンプトを拡張したものに,nyaosというシェルを組み合わせるのが良さそうです.

ファイルのダウンロード

ckwは下のサイトから落としました.
ckw 0.8.10 改造版を更に改造した(修正しただけ)

nyaosは下のサイトから,stable版の3.0.0_1のWindows binaryを落としました.
NYAOS.ORG - NYAOS 3000

ckwとnyaosは同一フォルダに入っているものとしてください.私の場合は両者ともC:\Program Files\ckwに入れました.

ckwとnyaosの連携

Ckw*exec:  cmd.exe

と書いてあるところを,

Ckw*exec:  "C:\Program Files\ckw\nyaos.exe"

に直すだけでOKです.

コマンド履歴の保存設定

まずはコマンド履歴を保存するための設定について書きます.nayosを解凍したフォルダの中に_nyaというnyaosの設定ファイルがあるのでそれをテキストエディタで開いてください.そのファイルの中のどこかに

option savehist "C:\Program Files\ckw\.history"

と書いてください.option +history と書いてある下ぐらいが見やすくて良いでしょう.これを書かないと履歴を保存してくれません.そして,ckwがどこで起動しても良いように.historyファイルへのパスはフルパスで書きます.なお,重要な点ですが,.historyというファイルは自分で作っておく必要があります.このとき,.historyという名前にしなくても構いません.また,中身は空で良いです.ただ,上で書いたsavehistのファイル名と対応付けるようにはして下さい.

右クリックから,対象フォルダでckwを開く

選んだフォルダをカレントフォルダにしてコマンドプロンプトを開く - デジタル - 日経トレンディネット
上記のURL先で紹介されているように,コマンドプロンプトを右クリックから開く方法があります.これをckwでもできないかと思い,実行してみました.基本的には上記URL先と同じようにやります.ただし,いくつか注意する点があるので,それを踏まえつつ行っていきたいと思います.

まずは,上記のURL先に習い,

引用1

 まず管理者権限のあるユーザーでログオンし、スタートメニューから「ファイル名を指定して実行」を選び、「regedit」と入力して「OK」ボタンをクリックする。レジストリエディタが起動したら、次のようにキーをたどる。

 HKEY_CLASSES_ROOT→Directory→shell

 「shell」を右クリックして「新規」−「キー」を選んで「cmd」というキーを作成する。

ところまで行って下さい.次に行うこととして,

引用2

「cmd」を選んだ際に右のペインに表示される「(既定)」をダブルクリックして、値のデータに「コマンドプロンプト」と入力して「OK」ボタンをクリックする(これはメニューに表示される項目名となる)。さらに、「cmd」を右クリックし、「新規」−「キー」を選んで「command」というキーを作成する。これを選んだ際に右のペインに表示される「(既定)」をダブルクリックして、値のデータに「cmd.exe /k "cd %l"」と入力して「OK」ボタンをクリックする(「/k」と「"cd %l"」の前にはそれぞれ半角スペースを1つ入れること)。

と書いてありますが,ここに関しては注意が必要です.まず,値のデータに「コマンドプロンプト」を入力するところですが,今回はコマンドプロンプトじゃなく,ckwなので,とりあえずckwとしときましょう(何でも良いです).cmdに関しては,既に登録されている場合,cmd2とかにしてもOKです.次のcommandというキーに関しては,名前を変えないでください.

大事なところ

最も重要なのは「cmd.exe /k "cd %l"」の部分です.ここを,

"C:\Program Files\ckw\ckw.exe" -cd "%l"

に書き換えてください.書き換えたらログインし直して下さい.そして,ckwを開きたいフォルダを右クリックして下さい.ckwという項目があるはずです.それを選ぶと,無事,右クリックしたフォルダでckwが起動するはずです.

補足

補足すると,-cd というのは,ckwが用意しているオプションで,-cd path の形式でpathに指定したフォルダでckwを開いてくれます.%lは,右クリックしたフォルダを表します."%l"のように,""で括っているのは,パスに半角空白を含むものが出ても,半角空白をコマンドの区切りと見なさないようにするためです.「cmd.exe /k "cd %l"」では,""の位置が違っており,このあたりで苦労しました.なんで「cmd.exe /k "cd %l"」ではcdも""で括られているんだろう….

ActionScriptのDictionary型とObject型の違い

ActionScriptで,オブジェクトへの参照を配列のキーとして持ちたい場合がある.そんなときに使えるのがDictionary型だ.しかしながら,Dictionary型を使わなくてもObject型にもオブジェクトへの参照をキーとして持たせられるように見えた.

FN0912002 - Dictionary()コンストラクタ - Flash : テクニカルノート には,Dictionary型の特徴は,オブジェクトへの参照をキーとして持てることだと書いてある.そこで,両者の違いを調べるために,簡単なコードを書いてみた.コードは以下のとおり.

package
{
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.utils.Dictionary;
		
	public class ActionScriptTest extends Sprite
	{
		
		public function ActionScriptTest()
		{
			
			var myObj:Object = new Object();
			var mc:MovieClip = new MovieClip();
			mc.name = "hoge";
			
			var mc2:MovieClip = new MovieClip();
			myObj[mc2] = mc;
			
			trace(myObj[mc2].name); // hoge
			
			var mc3:MovieClip = new MovieClip();
			trace(myObj[mc3].name); // hoge

			trace(myObj['[object MovieClip]'].name); // hoge
			
			var dic:Dictionary = new Dictionary();
			dic[mc2] = mc;
			trace(dic[mc2].name); // hoge
			trace(dic[mc3].name); // error!!
			
			
		}
	}
}

このコード中では,myObjにおいてmc2のオブジェクトへの参照をキーとして使って,mcへの参照を作っている.
期待する動作としては,mc2への参照をキーとして使ったときのみmcへとアクセス可能な状態ができていて欲しい.
しかしながら,実際にはmc3を用いたときにもmcへとアクセスできてしまう.Object型においてオブジェクトの参照をキーとして使ったときは,そのオブジェクトの文字列表現か何かを使うことになる.例えば,MovieClip型のオブジェクトをtraceすると,どのMovieClip型に対しても[object MovieClip]と表示される.そして,その文字列表現が同じとみなされるため,mc2を添字にしても,mc3を添字にしてもmcにアクセスできたのだろう.

一方,Dictionary型の方ではmc2とmc3を添字にした場合でははっきりと区別される.上記のコードのtrace(dic[mc3].name);の部分ではちゃんとエラーが出てくれることからも区別されていることが分かる.

ということで,オブジェクトへの参照を使うときはDictionary型を使いましょう.