Hatena::Groupperl

Perl Study Memory

There is a difference between knowing the path and walking the path.

自己紹介  | 初めてのPerl 第3版  | 続・初めてのPerl 改訂版  | アーカイブ  | 参考書籍・推薦図書

 | 

2010-03-24

$VERSION = eval $VERSION; の理由

| 21:39 | はてなブックマーク - $VERSION = eval $VERSION; の理由 - Perl Study Memory

こんばんは、AzureStone(あーじゅ・すとーん)です。

Me not english. I'm not good at English.

二年ぶりにTripletaiLでコーディングしようと思った今日この頃です。

ディスパッチャの部分をCatalystTripletaiLで比べたいなぁと思いTripletaiLのソースコードを

読み始めたのですが、少し気になったことがありました。それが、下記のコードです。

Tripletail.pm

  17  our $VERSION = '0.49';
  18  our $XS_VERSION = $VERSION;
  19  $VERSION = eval $VERSION;

これはいったいなんのためにしているのだろうか?

例えば、リスト1のようなものだとだめなのだろうか?と考えていました。

リスト1

our $VERSION = '0.49';
our $XS_VERSION = $VERSION;

何故、evalしているのかがよく理解できません。一瞬例外処理?とか勘ぐりましたが、明らかに違います。もし例外処理であれば、リスト2のようになっているはず。

リスト2

our $VERSION = '0.49';
our $XS_VERSION = $VERSION;

eval {
  $VERSION = $VERSION;
}; if ($@) { print "error!! $@\n"; }

そこで改めてPerlのevalを整理してみました。以下の二つ

  1. 引数を文字列ではなくプログラムとして解釈する
  2. 例外を補足するために利用する
    • この場合は、evalブロックを使用しなければいけない。
    • eval {};

先程も書いた通り今回、疑問に思っているコードは、2の例外処理に使用するものではなく明らかに1だと思う。しかし、一見意味ないように見えるのは私だけでしょうか?

僕が、想像しているevalとは、リスト3のような感じです。

リスト3

#!/usr/bin/perl -l

use strict;
use warnings;

my $num = 1;

my $test_01 = 'print $num';

print $test_01;

eval $test_01;

1;

リスト3の実行結果

azurestone@hoge:~/tmp/perl/eval$ perl test-eval01.pl
print $num
1
azurestone@hoge:~/tmp/perl/eval$

実行結果も想定の範囲内です。

色々と疑問になって調べてみました。

そうするとやはり同じ疑問を持つ方がいらっしゃいました。

この記事では、アンダースコアがつけていることによって文字列リテラルとして扱われる。

そのため、

1.12_01 < 1.12_02

という判定が出来ない。これを判定可能にするためには、浮動小数点数リテラルに変換しなくては行けない。そこでevalを使えば変換可能となる。

というお話です。

ところが上記の一番最初に疑問に思ったコードには、アンダースコアなく最初から浮動小数点数リテラルなのでなおさら疑問です。

結局、問題が解けず謎のままです。。。


本日おすすめの書籍

tokuhiromtokuhirom2010/03/25 08:58CPANにおいては、0.01_01 のようなバージョン番号は開発版につけるバージョン番号です。
ですので、おそらく TL がデベロッパーリリースする際に eval をいれたのではないかとおもいます。

hiohio2010/03/25 10:32修正中とかは普通に 0.01_02 みたいな番号のこともあるので、いちいちそこまでいじるのも面倒っていう横着ですね><。
ちなみに文字列にしてるのは、 $VERSION = 0.01_02 だと、 version 0.0102 って解釈されてしまうためです。
バージョン指定の判定(useや->VERSION)の他に、
make dist のときと、XSロードの時にこの違いが必要になります。

hiohio2010/03/25 10:37あ、バージョン比較の時は数値としての値が欲しくて(数値0.0102が欲しい)、
distやXSロードのときは文字列としての値が欲しい(文字列'0.01_02'が欲しい)
っていう感じです。

azurestoneazurestone2010/03/25 23:08tokuhiromさん・hioさん

コメントありがとうございます!
とても嬉しいです!!!

01:
 CPANでは、開発版(修正中)のときはアンダースコアをつけるのですね。
 つまり開発版(修正中)を想定したわけですね。

02:
 そして文字列と数値の両方を持たせる意味は、
 バージョン比較の時に数値を使い
 XS実行時には、文字列を利用するためだったのですね!

なるほどこれでやっと理解しました。
今、外は雨が降っていますが、おかげさまで頭の中が晴れました!!!

ありがとうございます ^ー^

MilkaMilka2014/05/06 16:56Uneaeallrlpd accuracy, unequivocal clarity, and undeniable importance!

 |