トップ 最新 追記

どんぞこ日誌

2003|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|07|08|12|
2007|01|04|08|12|
2008|01|02|03|04|06|07|08|10|11|12|
2009|01|02|04|05|06|07|08|09|11|12|
2010|01|03|04|07|08|10|11|12|
2011|01|02|03|04|05|06|07|08|10|12|
2012|01|02|03|05|06|07|08|09|10|
2013|01|02|07|08|09|
2014|08|09|
2015|08|
2016|06|07|12|
2017|01|03|08|
2018|03|
2022|03|
2023|03|
2024|02|07|10|

同人関連(どんぞこ楽屋) | 旧い雑文   


■2009-02-16

* [Perl] Template::Stash::XS使用時のlengthB!

 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));
  }
[]

■2009-02-19

* [Perl][メモ] Template::Stash::XSとVmethodのlength続きB!

  先日の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-05-23

[]