■2009-05-12
* [Perl][メモ] TTのvmehtodの件
前書いたTemplate::Stash::XSのlengthの件、他にもUnicodeなハッシュキーを扱えないという問題もあったみたい(rt.cpan.org)。以下左記ページから:
use strict;
use warnings;
use utf8;
use Template;
binmode STDOUT, ':utf8';
# $Template::Config::STASH = 'Template::Stash';
# ↑これをコメントアウトすれば適切な動作
Template->new()->process(\*DATA, {
ascii => 'key',
utf8 => '鍵',
hash => {
key => 'value',
鍵 => '値'
},
str => 'カワカマス'
});
__DATA__
ascii = [% ascii %]
hash.$ascii = [% hash.$ascii %]
utf8 = [% utf8 %]
hash.$utf8 = [% hash.$utf8 %]
str.length = [% str.length %]
結果:
ascii = key hash.$ascii = value utf8 = 鍵 hash.$utf8 = str.length = 15
[ツッコミを入れる]
[]
■2009-04-21
* [Perl][今月のAcme] Perl愛者へ12の質問
「異性愛者」へ12の質問を基にした○○愛者へ12の質問に触発されて。
Perl愛者へ12の質問
- あなたのPerl愛の原因はなんだと思いますか?
- 自分がPerl愛なのだと初めて判断したのはいつですか?どのようにですか?
- Perl愛は、あなたの発達の一段階ではないですか?
- Perl愛なのは、PHPを恐れているからではないですか?
- 一度もPHPでプログラミングしたことがないなら、なぜ、Perlを使ったプログラミングの方がよいと決められるのですか?あなたは単に、よいPHPの経験がないだけなのではないですか?
- 入社面接でPerl愛者であることを告白したことがありますか? その時の面接官の反応はどうでしたか?
- Perl愛は、他人にわかるコードを書く限り、不愉快なものではありません。それなのに、なぜ多くのPerl愛者は、他人をもPerlに引き込もうと誘惑しようとするのでしょうか?
- 知らない間にすごい勢いでCPNAモジュールをインスコする人の多くがPerl愛者です。あなたは自分のプロジェクトチームにPerl愛者(特に年季の入ったやつ)を入れることを安全だと思いますか?
- Perl愛者はなぜあんなにあからさまで、いつでも彼らのCPANを見せびらかすのでしょうか? なぜ彼らは車輪の再発明をすることができず、公衆の面前で「それプラ」とか言ったり、手書き正規表現をDisるなどして、CPANモジュールを見せびらかすのでしょうか?
- forとforeachというのは構文的にも意味論的にも明らかに異なっているのにどっち使ってもいいなんて、あなたはそのような言語で本当に満足いくプログラミングができますか?
- Perlに触れた初心者の多くは、英語なドキュメントでのサポートが受けられるにもかかわらず、今日では、一年以内にPerlを始めるプログラマの半分がやがてPerlから離れるといわれています。なぜPerlとの関係というのは、こんなにうまくいかないのでしょうか。
- このように、Perl愛が直面している問題を考えるにつき、あなたは自分の子供にPerl愛になってほしいと思いますか?セラピーで彼らを変えるべきだとは思いませんか?
[ツッコミを入れる]
[]
■2009-02-19
* [Perl][メモ] Template::Stash::XSとVmethodのlength続き
先日のTemplate::Stash::XS使用時のlengthで、unicodeに対応するようパッチをあててみたのですが、そもそもscalar_dot_length使わなくてもよいんじゃないかという気がしてきて、
--- xs/Stash.xs 2009-02-19 14:33:44.000000000 +0900
+++ xs2/Stash_del_len.xs 2009-02-19 14:37:47.000000000 +0900
@@ -115,7 +115,7 @@
{ "join", list_dot_join, NULL, NULL },
{ "keys", NULL, hash_dot_keys, NULL },
/* { "last", list_dot_last, NULL, NULL }, */
- { "length", NULL, NULL, scalar_dot_length },
+/* { "length", NULL, NULL, scalar_dot_length }, */
で
use Benchmark qw( timethese );
use strict;
use utf8;
my $count = 10000;
my $tmpl_pp = Template->new( { STASH => Template::Stash->new() } );
my $tmpl_xs = Template->new( { STASH => Template::Stash::XS->new() } );
my $tmpl_xs2 = Template->new( { STASH => Template::Stash::XS_del_len->new() } );
my $str_unicode = 'あいうえお' x 1000;
my $body = "[% str.length %]";
timethese($count, {
'xs' => sub {
my $ret = '';
$tmpl_xs->process( \$body, { str => $str_unicode }, \$ret );
},
'xs2' => sub {
my $ret = '';
$tmpl_xs2->process( \$body, { str => $str_unicode }, \$ret );
},
'pp' => sub {
my $ret = '';
$tmpl_pp->process( \$body, { str => $str_unicode }, \$ret );
},
});
(Template::Stash::XSは先日のパッチをあてたもの)
結果:
pp: 9 wallclock secs ( 8.12 usr + 0.00 sys = 8.12 CPU) @ 1231.53/s (n=10000) xs: 7 wallclock secs ( 7.32 usr + 0.02 sys = 7.34 CPU) @ 1362.40/s (n=10000) xs2: 7 wallclock secs ( 7.33 usr + 0.01 sys = 7.34 CPU) @ 1362.40/s (n=10000)
ほぼ大差ないのでscalar_dot_length自体必要なさそうな。
[ツッコミを入れる]
[]
■2009-02-16
* [Perl] Template::Stash::XS使用時のlength
template-toolkitでunicode文字列に対してバーチャルメソッドlengthを使うと、文字数ではなく、バイト数が返ってきて、でもsplitとかmatchとかはちゃんとunicodeに対する動作をしてます。
だいたいTemplate::VMethods::text_length自体呼ばれてないし、ってなわけで色々試してたら、Template::Stash::XSを使ったときだけ生じるので、Stash.xsをみたらscalar_dot_lengthで定義されてました。
use strict;
use utf8;
use Template;
my $tmpl = Template->new();
my $ret = '';
my $body =<<BODY;
length -- [% str.length %]
split_size -- [% str.split('').size %]
BODY
$tmpl->process( \$body, { str => 'あいうえお' }, \$ret );
↑本当は両方5になると思うのだけど、Stash::XSを利用している場合はlengthが15。で、下記のようなパッチ(Template-2.20)をあてたのですが、これって今まで問題にならなかったのかしら? あるいは私が何か勘違いをしているのか……
--- xs/Stash.xs.bak 2009-02-16 11:20:09.000000000 +0900
+++ xs/Stash.xs 2009-02-16 11:41:15.000000000 +0900
@@ -1125,8 +1125,16 @@
/* scalar.length */
static SV *scalar_dot_length(pTHX_ SV *sv, AV *args) {
STRLEN length;
+#if PERL_VERSION >= 8 /* Perl 5.8 and later */
+ if ( SvUTF8(sv) ) {
+ length = sv_len_utf8( sv );
+ }
+ else {
+ length = sv_len( sv );
+ }
+# else
SvPV(sv, length);
-
+# endif
return sv_2mortal(newSViv((IV) length));
}
[ツッコミを入れる]
[]


