2007-04-27(Fri)
filenameプラグマの使い途(その2、ファイル名のエスケープ処理)
たとえばsamba上にあるファイルに対してローカルで処理するコードを書いていたけど、どうせならサーバで動かせばいいんじゃね? と思って実行しようと思ったらファイル名のエンコードが違ってるってのは良くあることだと思う(よね?)。
cp932とeucjpの違いとかなら
use encoding 'cp932'; use filename \&_convert; BEGIN { require Encode; my $enc = Encode::find_encoding($^O eq 'MSWin32'? 'cp932': 'eucjp'); sub _convert { my $filename = shift; if (utf8::is_utf8($filename)) { $enc->encode($filename); } else { $enc->decode($filename); } } }
――とかで対応できるし、何らかのエスケープされている時は
2007-04-26(Thu)
filenameプラグマの使い途(その1、encodingプラグマとの併用)
メンテナの方から蛇蝎のごとく嫌われているencodingプラグマですが*1、使いようによっては便利です。
でまあこんなコードを書いたりするのですが、
use encoding 'cp932', STDIN => 'cp932', STDOUT => 'cp932'; use open IO => ':encoding(cp932)'; # CP932な文字列を含んだコード
――これだとマルチバイトなファイル/ディレクトリを扱えないというか、自前で変換コードを書かないといけなくて、少なくともjperlの代わりにはならない。
というわけでそれを自動化するプラグマとしてのfilename。
use encoding 'cp932', STDIN => 'cp932', STDOUT => 'cp932'; use open IO => ':encoding(cp932)'; use filename 'cp932', ':globally'; # CP932な文字列を含んだコード
これで一歩jperlに近づいた、はず。
ところで、openプラグマにも:globallyな指定は欲しいところ*2。
ファイルを扱うCORE::*関数はまだまだあるんだよね……
適当にコードを書いていたら足りない関数があるのに気付いた。調べたらけっこうあるのね。
Functions for filehandles, files, or directories
-X, chdir, chmod, chown, chroot, fcntl, glob, ioctl, link, lstat, mkdir, open, opendir, readlink, rename, rmdir, stat, symlink, sysopen, umask, unlink, utime
まあ使うモノから順に埋めていけばいいとして、ファイルテスト演算子はどうすりゃいいんだろ。
このあたりのことを考えると、標準機能としてサポートして欲しいなぁ。。。
use encoding ':locale'とかできるようになってたのね。
Perl | |
知らんかった。
openプラグマでも使えるみたいだし、filenameプラグマでも使えるようにするか。役に立つか微妙だけど*3。
2007-04-25(Wed)
filenameプラグマを作ってみたよ。
とりあえず作ってみた。たぶん動くんじゃないかな?
これを使って何をしたいかはまた後で。
名前
filename - utf8文字列なファイル名を変換したり、読み出したファイル名をutf8文字列に変換する方法を指定する
概要
use filename 'cp932'; open my $fh, '<', $filename;
use filenname 'cp932', qw/:globally/; # modify CORE::GLOBAL my $fh = IO::File->new( $filename, 'r' );
use filename \&_convert_cp932; open my $fh, '<', $filename; use Encode; my $enc = Encode::find_encoding('cp932'); sub _convert_cp932 { my $filename = shift; if (utf8::is_utf8($filename)) { $enc->encode($filename); } else { $enc->decode($filename); } }
注意
ファイルハンドル周りは挙動がよく分からないので、これで正しいのか自信がないです。
1引数のopen()には対応していません(すべき?)。
sysopen()にも対応していません(すべき?)。
予定
どれを使うか引数で指定できるようにしたほうがいい気がする。
Exporterを使うべきか悩みどころ。
希望
encodingプラグマと一緒に配布するとうれしいんじゃないかな?
2007-04-20(Fri)
utf8文字列のファイル名の扱いはどうなってるんでしょう?
気が利いているPerlのことですから、utf8文字列*1でopenすればファイルシステムに適切な形で扱われるものだと思いきや、そのままファイル名として扱われるっぽい。
えーっ。Perlのくせに気が利いてないなぁ。入出力ストリームに対しては:encoding()等でフィルタリングしてくれるくせに。
やっぱさあ、utf8文字列をファイル名として渡したら、適当に変換して欲しいじゃん。まあPerl様が自分で変換するのがイヤだって言うのなら、自分で変換処理を書くからそれを指定させてくれよ、と思うわけ。
――というわけで、きっと誰かが既に作ってそうなので、どのモジュールなのかご存じの方がいましたら教えてくださいな。自分で書くのは面倒なので*2。
そもそもこういうのやりたいときはどーするんでしょ。CORE::openをフックするとか?*3
追記
もしそんなのがあるとすればfilenameプラグマとかで
# CP932に変換する use filename 'cp932'; use filename ':encoding(cp932)'; # convert()で変換する use filename \&convert; sub convert { my $utf8_filename = shift; my $encode_filename = Encode::encode('cp932', $utf8_filename); return $encode_filename; } use utf8; open my $fh, '<', '日本語ファイル名.txt'; ...
――とかになるのかな。いや、ディレクトリ名も含まれるべきだから、ちょっと違うかもしれない。
おそらくはブロックローカルにすべきなんだろうけれど。自作するんならやりかた知らないしなぁ。
名称はfilenameプラグマでいいのか?
まかまかさんのアドバイスでなんとかなりそうな予感。CORE::*じゃなくてCORE::GLOBAL::*ね。
CPANで検索かけてpodも見つけた。
http://search.cpan.org/~nwclark/perl-5.8.8/pod/perlsub.pod#Overriding_Built-in_Functions____
でまあ、まじめにやると
- open()、opendir()でutf8文字列の時に変換する
- readdir()、glob()ではutf8文字列に変換する
必要があるわけで。
他にもあるかな?
あとはスコープの設定かー。encodingもスコープ関係ないんで同じでいいか。。。
2007-04-19(Thu)
「表現する気がない人のためのWeb2.0」は順調に進行しているようだ
Web2.0 | |
――と、Twitterの流行(らしきもの)を見ていて思った。
それを見る人の事はあまり考慮されていない点は変わってないようだけど。
変わってないといえばコミュニケーションのなさも改善される様子はないっぽい。そのあたりを気にしてる人は少なそうだから*1仕方ないけれど。
ひとりの表現を増やすよりコミュニケーションによってネタを増やす方向に行ったほうがいいと思うんだけどなぁ。僕が考えたようなモノは流行らないにしても、コミュニケーションのコストを下げつつ充実させるようにはならないものかしらん*2。
2007-04-18(Wed)
livedoorクリップで未クリップURLのコメントを表示が微妙におかしい気がするよ。
* | |
「このページはまだクリップされていません。」と出すんなら、そこで「このURLをクリップする」への遷移があるべきだ。というか既にクリップされていればできるし。
それにログイン状態であるにも関わらず「今すぐ登録/ログイン」のボタンを表示するのも変だ。
たぶん「このURLのコメントを表示する」機能を使ってる人が少なくてレポートがいってないんだと思うんだけど、どこにレポート上げればいいんじゃろ。
追記
非公開でクリップされている一度でもクリップされると僕が想定している状態になってます。
Operaを使うときの正しいフォント設定とは
Opera | |
僕がOperaを気に入ってる点はいろいろあるけれど、最も気に入ってるのは文字種別にフォント設定ができる点だったりします*1。
具体的には、欧米の文字はプロポーショナルで、日本語(およびCJK関係)は等幅に設定できるのが重要。だってさ、一般的な書籍はたいていそうやって組まれているし、コンピュータだってTeXを使う時はそう組まれるでしょ? ウェブページを見るときもやっぱりそう組んで欲しいのだ。
(ついでに書くと、上記のようにしておくと欧文はアンチエイリアスがかかって読みやすいってのもある)
ところで、昔のOperaは標準で上記のようになっていたのだけれど、最近は変わっているっぽいので修正方法のメモ。
- 標準のフォント――「ツール-設定-ウェブページ」にある「通常のフォント」は「Times New Roman」に、「等幅フォント」は「Courier New」に設定する。
- 「ツール-設定-詳細設定-フォント」の下にある「各言語の表示-文字別フォント」を下記のように指定する。
文字コードセット | プロポーショナルフォント | 等幅フォント |
---|---|---|
CJKの記号および句読点 (CJK Symbols and Punctuatuin) | MS 明朝*2 | MS ゴシック |
日本語(カタカナ) (Katakana) | MS 明朝 | MS ゴシック |
日本語(ひらがな) (Hiragaba) | MS 明朝 | MS ゴシック |
日本語(漢字) (Kanji) | MS 明朝 | MS ゴシック |
半角・全角形 (Halfwidth and Fullwidth Forms) | MS P 明朝 | MS ゴシック |
僕は明朝体派なので上記にしてるけど、ゴシック体のほうがいいならそちらに。
特に設定しない場合は「MS P ゴシック」に設定されていた気がします(いや、バージョンによって違ってたかな?)。
Unicodeのいい点はここだよね
Firefoxは言語ごとにフォントの設定ができて、それはそれで正しい気もするけれど。でも、日本語的には文字種ごとにフォントを変えられるほうが正しい。
そもそも日本語のプロポーショナルフォントってのはどうなのよ
専門じゃないのでよーわからんけど。等幅のほうが日本語的にはいいんじゃないのかな。
だとすればPが付くフォントは「欧文はプロポーショナル」に、「約物はものによっては半角」にすればいいんじゃないのに。というかそういうフォントはないの?
2007-04-13(Fri)
CDBI to DBIC
Perl, yapcasia2007 | |
YAPCのCDBI to DBICで「メソッドはコピペすればだいたい動くよ」と言ってた記憶があったんだけど、やってみたら動かない。
なんでー? とか思って読み直すと、コピペでだいたい動く(はず)なのはInstanceメソッドだけなのね。
Classメソッドをたくさん書いていたりする時は――search関係とか集約関数とか、手元のにはいろいろあるのですよ――DBIC::ResultSetのサブクラスを作って、Schemaのほうでは__PACKAGE__->resultset_class()を設定してあげる必要があるみたい。
CDBIではInstanceメソッドもClassメソッドもごっちゃになってやだなーと思っていたんで、DBICみたいな感じのほうがすっきりしていいです。が、移行するときはそのへんが大変っぽい気がしないでもない。
2007-04-07(Sat)
SQL::Abstract::Fulltext::MySQLの引数を直さないと。
Perl | |
http://asakura.g.hatena.ne.jp/asakura-t/20070405/1175745270
MySQLのドキュメントを読んでいたら、IN BOOLEAN MODE以外も指定できるのに気づいた*1。ので、下記のようにできなくちゃ駄目ですね。。。
my @rows = CDBI::Foo->search_where({ -fulltext => { -match => 'description', -against => '+foo +bar', -modifer => 'in boolean mode', # or 'with query expansion' }, });
2007-04-06(Fri)
BOFとか懇親会とか
yapcasia2007, C&C | |
記憶に残っているうちに。
(このような話をしたというより、お話している時にorあとで思ったことです)
ここギコさんとロカポイントの話
- ロカポイントの事はよーわかっとらんのに適当なこと言ってごめんなさい。
- 僕としては出先から自宅(or事務所)までの経路(乗り換え案内とか)を調べるのにわざわざ住所をいれなくていいのが良いかも、とかそのくらいの認識です。
- 自宅(or事務所)をブックマークしとけ、って話もありますが。いろんなサービスで対応してるならブクマするより楽かなとか。
- 出先の位置情報はケータイで取得できるので問題なし(ロカポイントじゃないけどね)。
まかまかさんとゲームブックの話
- ウェブになってゲームブック(のようなもの)が復活するかと思ったらそうでもなかったね、的な。
- ケータイならとかちょっと思ったけど、いまどきはアプリで普通にゲームができるもんねぇ。。。
- ただ、東浩紀の言うポストモダン的なモノとしてのゲームなら作れそうかもね、とかあとで思った。
- 完成した(ボリュームのある)ゲーム(シナリオや設定など)を作るのはムリだけど1ネタくらいなら作れる(書ける)ので、それを統合して提供するのはアリじゃないかな、とか。
- (あとで書くかも)
shebangさんにはいろいろとご迷惑を
- 何度もお願いしてすみません。
- 「引っ越し先はまたYahoo!と一緒なんですか?」と聞いたら「違うよ。全然違うよ。」とかわされてしまいました。
ma.laさんに会えた!
- 一方的に会ってみたかっただけなのに、いろいろすみません。
- というかいろいろ吃驚した。
- んでもコンテンツを売るには演出とか編集が必要というか、ないと売り物にならないというか。選出されるのは出来不出来より運になっちゃうのは仕方がないと思ってます。
- おそらく「出来不出来」にしようとしても結局は「声の大きい」ものが選ばれちゃうしね。
- 出会い系はパッシブであるべきだと思うんですよ。「友達登録してくれ」とか「コミュニティに入る」とかアクティブすぎ。
- 「お気に入り」同士だったら……ってのでもまだアクティブすぎると思ってます(でも既存のよりはまだいい)。
- それなりに理想的だと思ってるのは「似た方向性の趣味の人を自動的にピックアップ」→「ざっとチェックしてみてよさげならお気に入り登録」→「双方が登録したらお知らせ」的なフローのもの。「似た方向性の趣味のピックアップ」が難しそうだけど。
- (あとで書くかも)
- 真逆の方向性だけど「興味のない事に関するニュース」をもっと見やすくしてほしいってのもある。
- 新聞だって1面とか掲載位置で記事に重み付けしてるし、雑誌だって目次や掲載位置で扱いで重み付けしてるのに、ほとんどニュースサイトはちゃんと重み付けしないで速報を重視してるってのはどうなのよ? って思う。特に過去記事の扱いがひどすぎる。
- (あとで書くかも)
- OperaはケータイとかDSとかWiiで使われてるので、そのへん向けに最適化するんなら無視できないよ! と主張するのを忘れてた。
弾さんにEncodeの事をちょっと聞く
- Jcodeメーリングリストで5.8のEncodeについていろいろやってた頃にリクエストや不具合報告を出していたのは秘密です。
- 文字コードの政治的な部分についていろいろご不満があるようでした。
- とりあえずEncodeのupdateをお待ちしています、はい。
2007-04-05(Thu)
SQL::Abstract::Fulltext::MySQLを書いてみた。
Perl | |
ちゃんと動作確認はしてないけど。
package SQL::Abstract::Fulltext::MySQL; use strict; use warnings; use Carp; my $org_recurse_where = main->can('SQL::Abstract::_recurse_where'); sub import { croak "must be require SQL::Abstract" unless $org_recurse_where; no warnings 'redefine'; *SQL::Abstract::_recurse_where = \&_recurse_where if $org_recurse_where != \&_recurse_where; } sub _recurse_where { my $self = shift; return $org_recurse_where->($self, @_) unless uc($_[1]) eq 'FULLTEXT'; _make_fulltext_where($self, @_); } sub _make_fulltext_where { my $self = shift; my $where = SQL::Abstract::_anoncopy($_[0]); # prevent destroying original my $ref = ref $where || ''; my $bind_col; my $match; my $against; my $boolean; while (my($k, $v) = each %$where) { my $k = uc $k; if ($k eq '-MATCH') { if (ref $v eq 'ARRAY') { $bind_col = $v->[0]; $match = join ', ', map +$self->_quote($_), @$v; } else { $bind_col = $v; $match = $self->_quote($v); } } elsif ($k eq '-AGAINST') { $against = $v; } elsif ($k =~ /-BOOLEAN(_MODE)?/) { $boolean = $v; } } my $where_sql = sprintf "MATCH ( %s ) AGAINST ( ? %s)", $match, ($boolean? 'IN BOOLEAN MODE': '') ; return $where_sql, $self->_bindtype($bind_col, $against); } 1; __END__
使い方としては、
package CDBI::Foo; use base qw/Class::DBI/; use Class::DBI::AbstractSearch; use SQL::Abstract::Fulltext::MySQL; # 以下略 package main; # WHERE MATCH ( description ) AGAINST ('+foo +bar' IN BOOLEAN MODE) my @rows = CDBI::Foo->search_where({ -fulltext => { -match => 'description', -against => '+foo +bar', -boolean => 1, }, });
――みたいな。Class::DBIの場合はClass::DBI::AbstractSearchを使うかClass::DBI::Sweetを*1使っているときに利用できます。
DBIx:ClassはSQL::Abstractを使っているので(確か)、useすれば-fulltextが使えるようになります(未確認動くのを確認しました)。
どこかでuse SQL::Abstract::Fulltext::MySQLしちゃうとSQL::Abstractを書き換えちゃうのでアレだけど。特定クラスだけ変更するのは面倒だから気にしてない。
本当はSQL::Abstract::Limitみたいに各種RDBMS互換にしたいけど、MySQL以外は知らないもので。。。
対応しやすくしてる(つもりな)ので、そのうちなんとかしたいなぁ*2。
2007-04-03(Tue)
SQL::Abstractって全文検索に対応してないのね。
Perl | |
RDBMSによって文法が違うから仕方ないけど。
SQL::Abstract::Fulltext::MySQLとか作るべきか。。。
YAPCの会場に9時に到着するにはラッシュ時に移動しなくちゃいけない。
Perl | |
やだなぁ。
やっぱ8時くらいに現地に着いてモスで時間を潰すべきか。
あと、蒲田より食事処が少ない気がするんだけどどーなんだろ。
2007-04-02(Mon)
CGMと言えば「ファンロード」だろうに、誰も取材してないっぽいのはなぜだ?
編集 | |
いやまあ「アウト」でもいいけど、「ファンロード」*1は現役なので。
気まぐれで「CGM」「ファンロード」で検索してみたら全然引っかからないので気になった。
CGMがどーのとか言ってるメディアが「ファンロード」を取り上げないのはともかく、ブログその他でも言及されてないっぽいのがちょっと不思議。
ネットとは関係ないって判断なのかと思うけれど、CGMの編集のあり方とかコミュニティの構築については参考になると思うのにねぇ。
*1:あれ、「ふぁんろーど」のほうが正しいんだっけ?
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 08 | 09 | 10 | 11 | 12 |
2007 | 02 | 03 | 04 | 05 | 06 | 07 | 10 | 11 | 12 |
2008 | 02 | 03 | 04 | 06 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 02 | 03 | 04 | 05 | 07 | 08 | 10 | 11 | 12 |
2013 | 01 | 05 | 07 |
2014 | 01 | 02 |
2016 | 01 |
2017 | 01 | 05 |
- UNIX ベース アプリケーション用サブシステム
- 特殊映像ラボラトリー第33回 「監督=プロデューサー アニメ会社は 流通革新を起こすか?」
- 中国産アニメ「功夫料理娘」がイロイロと良い感じ
- ASCII.jp:エヴァのガイナックスがYouTubeに来た本当の意味|渡辺由美子の「誰がためにアニメは生まれる」
- Business Media 誠:野島美保の“仮想世界”のビジネスデザイン:増える“ゲームっぽいコンテンツ”――ゲームの再定義競争 (1/3)
- 【レポート】TVアニメ『ゆるゆり』、OPテーマ「ゆりゆららららゆるゆり大事件」のPV撮影現場を直撃! (1) PV撮影現場を少しだけ紹介 | ホビー | マイコミジャーナル
- ASCII.jp:車のCMではなく、本気のアニメを――スバルの挑戦【後編】|渡辺由美子の「誰がためにアニメは生まれる」
- FJ(フィナンシャル ジャパン)オンライン: 『攻殻機動隊S.A.C. SSS 3D』
- 日本教の構造 山本七平の研究 「日本教の社会学」より
- ASCII.jp:車のCMではなく、本気のアニメを――スバルの挑戦【前編】|渡辺由美子の「誰がためにアニメは生まれる」
CORE::GLOBAL::open使えばよいんじゃないでしょうか。
殴り書きしてみましたが、とりあえず望みの動作に近い?
package filename;
use strict;
use Encode;
my %Encoding;
BEGIN {
*CORE::GLOBAL::open = sub (*;@) {
local *sym = shift;
if (@_ == 0) {
CORE::open (*sym);
}
elsif (@_ == 1) {
CORE::open (*sym, $_[0]);
}
elsif (@_ == 2) {
my $file = $_[1];
if (utf8::is_utf8($file)) {
$file = Encode::encode($Encoding{out}, $file);
}
else {
Encode::from_to($file, $Encoding{in}, $Encoding{out});
}
CORE::open (*sym, $_[0], $file);
}
};
}
sub import {
my ($name, @enc) = @_;
if (@enc == 1) {
$Encoding{in} = 'utf8';
$Encoding{out} = $enc[0];
}
elsif (@enc == 2) {
$Encoding{in} = $enc[0];
$Encoding{out} = $enc[1];
}
}
1;
ちなみに、open()だけじゃなくてopendir()もやらなくちゃとか、globはどーするねんとか、考えなくちゃいけないのはいろいろあるような気がします(だから自分ではあまりさわりたくない/笑)。
あとはFileHandleやIO::Fileなどの動作に影響があるのかが気になるところ(前記モジュールでもfilenameプラグマが動作して欲しい、という意味で)。
そうですねえ。それ考えると素直にopenに渡す前にファイル名を
コンバートした方がよいでしょうね。
あとfilenameを先にuseすればIO::Fileにも適用されます。
ちらっと作ってみましたが、多分こんな感じでいけると思います。
use utf8;
use PerlIO::via::EncodeFilename 'euc-jp';
# もしくはモジュールの中でTerm::Encodingなどを使って自動判別
open my $fh, '<:via(EncodeFilename)', 'にほんごのファイル名.txt';
ただ、FileHandleやIO::Fileを気にしているように、できるだけ既存のモジュールを変更したくないなぁと。結局はuse filenameしなくちゃいけないんだから、open()してるとこを変更するのも同じじゃん、て話もありますが。
あ、でも、opendir()やreaddir()、glob()も同様に扱えます? 扱えるなら問題なさそうですが。