Google グループは Usenet の新規の投稿と購読のサポートを終了しました。過去のコンテンツは引き続き閲覧できます。
表示しない

Funny phenomena on $_=~m/(.*)$/ with package NKF(perl-5.8.0)

閲覧: 3 回
最初の未読メッセージにスキップ

YAMADA Kunihiro

未読、
2003/06/04 9:55:362003/06/04
To:
山田邦博です。

Perl 5.8.0 を使い始めていますが、NKF パッケージを使った時に妙な現象に
出食わしました。

まず perl は、

$ perl -v
This is perl, v5.8.0 built for i386-linux-thread-multi
....

です。

システムは、Debian GNU/Linux Sarge (kernel 2.4.20) です。


現象を出す script の例は、

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
cat test2.pl
#!/usr/bin/perl

use NKF;

$ABC = "ABC";
$_ = nkf("-e",$ABC);

print "\n### testing for m// to { \$_ = nkf(\"-e\",\"$ABC\") }\n";
if (m/(.*)/) {
print "m/(.*)/ : \"$1\"\n";
} else {
print "m/(.*)/ : is FALSE\n";
}
if (m/^(.*)/) {
print "m/^(.*)/ : \"$1\"\n";
} else {
print "m/^(.*)/ : is FALSE\n";
}
if (m/(.*)$/) {
print "m/(.*)\$/ : \"$1\"\n";
} else {
print "m/(.*)\$/ : is FALSE\n"; # FALSE になってしまう
}
if (m/^(.*)$/) {
print "m/^(.*)\$/ : \"$1\"\n";
} else {
print "m/^(.*)\$/ : is FALSE\n"; # FALSE になってしまう
}

print "\n### testing for eq ###\n";
if($_ eq "ABC"){
print "\$_ eq \"ABC\" : OK\n"; # これは問題が起こらない
} else {
print "\$_ eq \"ABC\" : NG\n";
}

print "\n### testing for m/^...\$/ ###\n";
if(m/^ABC$/){
print "m/^ABC\$/ : OK\n";
} else {
print "m/^ABC\$/ : NG\n"; # NG になる。
}

$_ = "$_"; # Reassign a character string to $_

print "\nNow, reassined \$_ by : { \$_ = \"\$_\" }\n";
if(/^ABC$/){
print "m/^ABC\$/ : OK\n"; # 強制的に文字列化すると OK
} else {
print "m/^ABC\$/ : NG\n";
}
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

です。 これを実行すると、

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
$ ./test2.pl

### testing for m// to { $_ = nkf("-e","ABC") }
m/(.*)/ : "ABC"
m/^(.*)/ : "ABC"
m/(.*)$/ : is FALSE
m/^(.*)$/ : is FALSE

### testing for eq ###
$_ eq "ABC" : OK

### testing for m/^...$/ ###
m/^ABC$/ : NG

Now, reassined $_ by : { $_ = "$_" }
m/^ABC$/ : OK
$
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

となります。
要は、
$_ = nkf("-e","ABC");
としたものは、regular expression での行末 $ のマッチングができなくなる、
という現象です。
$_ = "$_";
と、強制的に文字列化するとこのパターンマッチングの問題は起こりません。
また、上記の例では書いてありませんが、
$tmp=$_;
$_=$tmp;
などと一旦別の変数を経由して再代入しても、この問題が起こらなくなります。

どうも、NKF 上のバグと言うよりも、perl の処理系の方の問題のような気が
するのですが、どんなもんでしょうか?

Shinji KONO

未読、
2003/06/04 10:03:102003/06/04
To:
河野真治 @ 琉球大学情報工学です。

In article <m2he76a...@owlin.tksa.gr.jp>, YAMADA Kunihiro <ki...@tksa.gr.jp> writes


> 要は、
> $_ = nkf("-e","ABC");
> としたものは、regular expression での行末 $ のマッチングができなくなる、
> という現象です。

あ、なんか、そういうのあったかも知れない。そのあたりの修正が
あったような気がします。nkf のversion が新しいのでは直っているかも。

> どうも、NKF 上のバグと言うよりも、perl の処理系の方の問題のような気が
> するのですが、どんなもんでしょうか?

まぁ、どっちでも直せるんでしょうけど、NKFの方を直す方が普通でしょう。

---
Shinji KONO @ Information Engineering, University of the Ryukyus,
PRESTO, Japan Science and Technology Corporation
河野真治 @ 琉球大学工学部情報工学科,
科学技術振興事業団さきがけ研究21(機能と構成)

YAMADA Kunihiro

未読、
2003/06/04 10:32:342003/06/04
To:
山田邦博です。

すみません、nkf の version を書き忘れました。
libnkf-perl 2.01-5
nkf 2.01-5
でした。

ko...@ie.u-ryukyu.ac.jp (Shinji KONO) writes:

> 河野真治 @ 琉球大学情報工学です。
>
> In article <m2he76a...@owlin.tksa.gr.jp>, YAMADA Kunihiro <ki...@tksa.gr.jp> writes
>> 要は、
>> $_ = nkf("-e","ABC");
>> としたものは、regular expression での行末 $ のマッチングができなくなる、
>> という現象です。
>
> あ、なんか、そういうのあったかも知れない。そのあたりの修正が
> あったような気がします。nkf のversion が新しいのでは直っているかも。

では、ソースを追っかけてみる事にしましょう。

Thanks.

Shinji KONO

未読、
2003/06/04 19:24:502003/06/04
To:
河野真治 @ 琉球大学情報工学です。

In article <m2el29c...@owlin.tksa.gr.jp>, YAMADA Kunihiro <ki...@tksa.gr.jp> writes


> すみません、nkf の version を書き忘れました。
> libnkf-perl 2.01-5
> nkf 2.01-5
> でした。

(う、僕の知らないversionかも...)

> >> $_ = nkf("-e","ABC");
> >> としたものは、regular expression での行末 $ のマッチングができなくなる、
> >> という現象です。

> では、ソースを追っかけてみる事にしましょう。

/* SvPV(result,o_len) does not work here. */
output = SvPVX(result);
o_len = rlen;
output_ctr = 0;

/* Convestion */
kanji_convert(NULL);
/* nkf_putchar(0); Null terminator */

RETVAL = result;
SvPOK_on(RETVAL);
/* We cannot use
SvCUR_set(RETVAL, strlen(output));
because output can contain \0.
*/
SvCUR_set(RETVAL, output_ctr);

のあたりで、最後にstrlen を設定にいくわけなんだけど、
そいつが問題なみたい。長さは output_ctr で確定してい
るんですけどね。

Inaba Hiroto

未読、
2003/06/10 11:43:212003/06/10
To:
稲葉です。

fj.comp.lang.perl の <3988455...@insigna.ie.u-ryukyu.ac.jp> の
記事において 2003年06月04日(水) 23時24分50秒頃、
Shinji KONOさんは書きました。

>> >> $_ = nkf("-e","ABC");
>> >> としたものは、regular expression での行末 $ のマッチングができなくなる、
>> >> という現象です。
>> では、ソースを追っかけてみる事にしましょう。

> /* Convestion */
> kanji_convert(NULL);
> /* nkf_putchar(0); Null terminator */
>
> RETVAL = result;
> SvPOK_on(RETVAL);
> /* We cannot use
> SvCUR_set(RETVAL, strlen(output));
> because output can contain \0.
> */
> SvCUR_set(RETVAL, output_ctr);
>
>のあたりで、最後にstrlen を設定にいくわけなんだけど、
>そいつが問題なみたい。長さは output_ctr で確定してい
>るんですけどね。

長さが設定されても、現在のPerl5においてはその次の
バイトが'\0'でterminateされていることを前提とする
コードが残ってます。少なくとも正規表現の「$」を判定
する部分はその一つです。なので、上のSvCUR_set()
の次で、

*SvEND(RETVAL) = '\0';

とする必要があります。resultにもう1バイト入れるだけ
のメモリが確保されている必要がありますが。

当然、長さは設定されているのでその気でコーディングすれ
ばNull terminateしなくてもいいはずですが、どれだけそう
なってないコードがあるか(Perlコア以外でも幾多のCPAN
moduleも考えると)わかりませんし。

#実は自分も昔、Null Terminateしなくなるコードを書いて
#しまった経験があるんですが。
---
稲葉 浩人 in...@st.rim.or.jp

新着メール 0 件