ハングアップの日々

2012年 1月分

2012/01/31

memo

2012/01/30

memo

2012/01/27

memo

2012/01/26

memo

2012/01/25

memo

2012/01/24

memo

2012/01/19

memo

2012/01/18

Perl の文字クラスの動作(続き)

 Perl 5.14 の文字クラスの動作をもう少し調べてみた。難しい。

"\x{17f}" =~ /(?u)[[:lower:]]/    → match
"\x{17f}" =~ /(?a)[[:lower:]]/    → unmatch ★
"\x{17f}" =~ /(?aa)[[:lower:]]/   → unmatch

"\x{17f}" =~ /(?iu)[[:lower:]]/   → match
"\x{17f}" =~ /(?ia)[[:lower:]]/   → match ★
"\x{17f}" =~ /(?iaa)[[:lower:]]/  → unmatch

"\x{212a}" =~ /(?u)[[:upper:]]/   → match
"\x{212a}" =~ /(?a)[[:upper:]]/   → unmatch ★
"\x{212a}" =~ /(?aa)[[:upper:]]/  → unmatch

"\x{212a}" =~ /(?iu)[[:upper:]]/  → match
"\x{212a}" =~ /(?ia)[[:upper:]]/  → match ★
"\x{212a}" =~ /(?iaa)[[:upper:]]/ → unmatch

"\x{df}" =~ /(?u)[[:lower:]]/     → match
"\x{df}" =~ /(?a)[[:lower:]]/     → unmatch ★
"\x{df}" =~ /(?aa)[[:lower:]]/    → unmatch

"\x{df}" =~ /(?iu)[[:lower:]]/    → match
"\x{df}" =~ /(?ia)[[:lower:]]/    → unmatch ★
"\x{df}" =~ /(?iaa)[[:lower:]]/   → unmatch

 LATIN SMALL LETTER LONG S (U+017F, ſ) と KELVIN SIGN (U+212A, K) は、case folding によって ASCII 範囲内の文字と同一視されるという点で、特別な文字である。LATIN SMALL LETTER SHARP S (U+00DF, ß) などとは、★の部分の動作が異なる。
 (?a) の動作は本当にややこしい。いっそ、(?u) と (?aa) だけにしてしまった方が分かりやすいのではないだろうか。

2012/01/17

memo

2012/01/16

Perl の文字クラスの動作

 先日の、Ruby や鬼雲で文字クラスの動作がおかしいと思われる件について、Perl 5.14 での動作を調べてみた。

"\x{17f}" =~ /(?iu)\w/     → match
"\x{17f}" =~ /(?iu)[\w]/   → match
"\x{17f}" =~ /(?iu)\W/     → unmatch
"\x{17f}" =~ /(?iu)[\W]/   → unmatch

"\x{17f}" =~ /(?ia)\w/     → unmatch ★
"\x{17f}" =~ /(?ia)[\w]/   → match ★
"\x{17f}" =~ /(?ia)\W/     → match
"\x{17f}" =~ /(?ia)[\W]/   → match
"s" =~ /(?ia)\w/     → match
"s" =~ /(?ia)[\w]/   → match
"s" =~ /(?ia)\W/     → unmatch
"s" =~ /(?ia)[\W]/   → unmatch

"\x{17f}" =~ /(?ia)\p{ASCII}/     → unmatch
"\x{17f}" =~ /(?ia)[\p{ASCII}]/   → unmatch
"\x{17f}" =~ /(?ia)\P{ASCII}/     → match
"\x{17f}" =~ /(?ia)[\P{ASCII}]/   → match
"s" =~ /(?ia)\p{ASCII}/     → match
"s" =~ /(?ia)[\p{ASCII}]/   → match
"s" =~ /(?ia)\P{ASCII}/     → unmatch
"s" =~ /(?ia)[\P{ASCII}]/   → unmatch

"\x{17f}" =~ /(?iaa)\w/    → unmatch
"\x{17f}" =~ /(?iaa)[\w]/  → unmatch
"\x{17f}" =~ /(?iaa)\W/    → match
"\x{17f}" =~ /(?iaa)[\W]/  → match

 文字クラスの内外で結果が一致していないものには ★ を付けた。(?ia) が、不思議な挙動となっている。
 一方、鬼雲 5.12.1 の (?ia) の挙動は以下の通り。

"\x{17f}" =~ /(?ia)\w/     → unmatch ★
"\x{17f}" =~ /(?ia)[\w]/   → match ★
"\x{17f}" =~ /(?ia)\W/     → match
"\x{17f}" =~ /(?ia)[\W]/   → match
"s" =~ /(?ia)\w/     → match
"s" =~ /(?ia)[\w]/   → match
"s" =~ /(?ia)\W/     → unmatch ★
"s" =~ /(?ia)[\W]/   → match ★

"\x{17f}" =~ /(?ia)\p{ASCII}/     → unmatch ★
"\x{17f}" =~ /(?ia)[\p{ASCII}]/   → match ★
"\x{17f}" =~ /(?ia)\P{ASCII}/     → match
"\x{17f}" =~ /(?ia)[\P{ASCII}]/   → match
"s" =~ /(?ia)\p{ASCII}/     → match
"s" =~ /(?ia)[\p{ASCII}]/   → match
"s" =~ /(?ia)\P{ASCII}/     → unmatch ★
"s" =~ /(?ia)[\P{ASCII}]/   → match ★

鬼雲の方がより怪しい動きをしているが、どういう仕様であるべきかを明確にしないことには、下手にいじらない方が良さそうである。

memo

2012/01/15

memo

2012/01/14

FreeBSD 9.0

 数日前に FreeBSD 9.0 が公開された。最後に FreeBSD をインストールしたのは 10年以上前のことだろうか。(最後に使ったのはおそらく 5年くらい前。) VMware Player に FreeBSD 9.0 (amd64) をインストールしてみることにした。
 インストーラは昔とさほど変わらず、テキストベースの画面だった。キーボードの選択で jp106 と jp106x というのがあり、何かと思ったが、jp106x は、Ctrl と Caps が入れ替わっているようだ。何も考えずに、デフォルトの設定のままインストールを進めていったところ、最低限のものしか入っていない状態でインストールが完了してしまった。X やデスクトップ環境も入っておらず、ちょっと困った。FreeBSD ハンドブック を参考に、以下の手順で xorg, gnome2, VMware tools をインストールして、gnome が立ち上がることが確認できた。(最初は、VMware tools を入れない状態で X を動かしたところ、マウスが動かず途方に暮れた。)

% su
# pkg_add -r xorg
# pkg_add -r gnome2
# pkg_add -r compat6x-amd64
# mount -t cd9660 /dev/cd0 /mnt
# tar xf /mnt/vmware-freebsd-tools.tar.gz
# cd vmware-tools-distrib/
# ./vmware-install.pl
# exit
% echo "/usr/local/bin/gnome-session" > ~/.xinitrc
% startx

Onigmo 5.12.1、clang 3.0

 FreeBSD 9.0 には、clang 3.0 が入っているので、それを使って Onigmo 5.12.1 をコンパイルできるか試してみた。
 以下のコマンドで、あっさりビルドとテストが通ってしまった。あまりにも簡単で拍子抜け。

% env CC=clang ./configure
% make
% env LD_LIBRARY_PATH=.libs ./testpy.py UTF-8

2012/01/12

Python 2, 3 で標準出力のエンコーディングを設定

 「cp932で表現できない文字がたまに混ざるユニコード文字列をWindowsのコンソールにprintしたい場合 - 西尾泰和のはてなダイアリー」を見て、Python 2 と 3 で共通の方法で、同じことをできないかと考えてみた。
 実は、以前の io.open を使った方法を使えば、io.open には errors 引数があるので、これを前述のサイトと同じように設定すれば、指定されたエンコーディングに変換できない文字を代替表記に置換して出力できる。ただ、以前の方法では、Python 自身が出力するエラー出力が Python 2 では出力されないという問題があることが分かった。
 以前の方法では、Python 2 で sys.std(out|err).write 関数に bytes 型が渡されるのを回避するために、print 関数をフックしていたが、今回は sys.std(out|err).write 関数自体をフックすることにした。

    class TextWriter:
        def __init__(self, fileno, **kwargs):
            kw = dict(kwargs)
            kw.setdefault('errors', 'backslashreplace')         # \uXXXX 形式による代替表記をデフォルトに設定
            kw.setdefault('closefd', False)
            self._writer = io.open(fileno, mode='w', **kw)
            self._write = self._writer.write
            # work around for Python 2.x
            self._writer.write = lambda s: self._write("" + s)  # Unicode 文字列に変換
        
        def getwriter(self):
            return self._writer
    
    sys.stdout = TextWriter(sys.stdout.fileno(), encoding=outenc).getwriter()
    sys.stderr = TextWriter(sys.stderr.fileno(), encoding=outenc).getwriter()

 以上のコードで、Python 2, 3 共通の方法で、標準出力・標準エラー出力のエンコーディングと、エンコードエラー発生時の処理方法を設定できるようになった。ただ、少々長いのが難点だ。

memo

2012/01/10

Ruby, 鬼車

 Ruby の Redmine に、/[\W]/i の動作がおかしいとの報告が来ている。

 鬼雲にも影響があるか確認したところ、/(?ia)[\w]+/ が ASCII 範囲外の U+212A (KELVIN SIGN) と U+017F (LATIN SMALL LETTER LONG S) にもマッチしてしまうことが判明。他にも、/(?iu)[\p{ASCII}]/ が U+212A と U+017F にマッチしたり、/(?iu)[\P{ASCII}]/ が "s" にマッチしてしまう。
 文字クラスの中に、\w や \p{} などが含まれている際の case fold 処理に問題がある。しかし、よい修正方法が思いつかない。

memo

2012/01/05

memo

2012/01/02

memo


Copyright (C) 2012 K.Takata