まだ重たいCMSをお使いですか?
毎秒1000リクエスト を捌く超高速CMS「adiary

2007/01/13(土)perl の import の働き

use と require と import の関係

perldoc perlmodによると、use というのは次と等価と書かれています。

use Module;
use Module LIST;

はそれぞれ、

BEGIN { require Module; import Module; }
BEGIN { require Module; import Module LIST; }

と等価になります。

BEGINとは?

BEGIN というのは、perl がそのソースファイルをロード中、発見次第最初に1回だけ実行する構文であるという意味です。少しフォローしておくと、モジュールのロードは、@INCにあるパスを順番に見てロードされますが、lib/ 以下に自作モジュールがあるとき、

push(@INC, './lib');
use Module;

はエラーとなります。先に use (BEGIN内構文)が実行されて、@INCにパスを追加する前にモジュールのロードが発生するからです。

use lib './lib';
use Module;

や、

push(@INC, './lib');
require Module; import  Module;

とする必要があります。END { }なんてのもありますが、脱線はこれぐらいにして本題に入りましょう。

import がない場合

モジュールをロードし perl の名前空間に展開するならば、基本的には require すれば足ります。

---test.pm---
package test;
sub new {
	return bless({}, shift);
}
---test.pl---
require test;
my $obj = new test();

ちなみに require では実行する度に処理されてしまうので無駄になりますから、

use test ();		BEGIN { require test; } と等価

とします。import しなくても、ロードしたライブラリを使えるわけです。ではインポートとは何なのか?

import の役割

import は外部ライブラリの関数をあたかも自分の関数のように扱う仕組みです。正確に言えば、外部ライブラリの関数を自分の名前空間内に展開する仕組みが import です。例を見てみましょう。

---test.pm---
use Exporter;		#←必須です
package test;
our @ISA    = qw(Exporter);	#←必須です
our @EXPORT = qw($X &sum);
our @EXPORT_OK = qw($Y);
our $X = 10;
our $Y = 20;
sub sum {
	return ($_[0]+$_[1]);	#渡された引数2つを加えて返す処理
}
print "in test.pm : X=", \$X, "\n";

呼び出し側はこんな感じです。

use test;	# BEGIN {require test; import test;} と等価
our ($X, $Y);
print "X=$X ", \$X, "\n";
print "Y=$Y\n";
print sum(5,3),"\n";

として実行してみます。

in test4.pm X=SCALAR(0x93bc130)

X=20 SCALAR(0x93bc130)

Y=

30

となります。test という名前空間内の変数 $X、関数 sum が、import した側で使えるようになっています。perl 的に正確に言えば、$test::x と &test::sum の示す実体が(内部的な実体のポインタが)それぞれ $MAIN::x、&MAIN::sum にコピーされたことになります。その証拠に、リファレンスをとって実体を調べると、ともに同じ実体である SCALAR(0x93bc130) を示しています。

import される関数は、モジュール側で @EXPORT に代入されているものになります

import の引数は何?

import は配列引数を取れることになっています。これは、モジュール側で @EXPORT および @EXPORT_OK に代入されているもののうち、どれをインポートするか指定する役割があります。

ですから、さきほどのソースで、

use test qw(&sum $Y);

と変更すると次のような結果になります。

in test4.pm X=SCALAR(0x953e1b8)

X= SCALAR(0x94fd660)

Y=10

30

$Yがインポートされている反面、$X が test.pm 内の実体とは違うものを示していることが分かります。

関連記事

2007/01/11(木)Version1.03 リリース情報

ダウンロードはこちらから

Ver1.01→Ver1.03の変更点

  • 擬似データベース(外部DBなし)運用時の文字検索処理が速くなるようにしました。
  • span.adminmenu を諸事情により復活させました。
  • クラス指定記法において、クラス名に半角スペースを許可しました。*1
  • Satsukiテーマの色違い(緑、ピンク、オレンジ)を作成・収録しました。
  • まりやテーマ、しおんテーマを収録しました。
  • 元日(大晦日深夜)は日付変更時間処理を行わないようにしました。
  • ISBNコード13桁化に対応しました。(参考資料:はてなの記事
  • adiary.cgi を Apache 1.3.x において DirectoryIndex 指定すると、mod_rewrite 環境と誤判別する問題を修正しました*2
  • uploader.conf.cgiuploader.conf.cgi.sample として配布するようにしました。*3
  • 【スケルトン】_main, _main_onelogが変更になりました*4
  • 【fix】URL自動リンクが有効のとき、[http://~:ほげほげ]が動作しないバグを修正しました(Thanks to 最低人間さん)。
  • 【fix】ID記法によるトラックバック使用時、新着報告がうまく行われていなかったバグを修正。
  • 【fix】UTF-8版で注釈が文字化けする問題を修正しました。*5
  • 【fix】クラス指定記法「::class_name」が動作していなかったバグを修正しました。
  • その他、細々とした調整と修正。

Version1.00以降(RC含む)からの乗り換え

そのまま上書きしてください。

デザイン変更機能を使用している方は使用中のデザインを一度開きそのまま保存してください。

β版からの乗り換え

不可能ではありませんが特にアナウンスしません。よくわからない場合は、一度Version1.00へ一度アップグレードしてから、再度アップグレードすることを勧めます。

*1 : 複数クラス指定に使用します

*2 : adiary は DirectoryIndex での運用より、mod_rewriteでの運用をお勧めします

*3 : uploader.conf.cgi には画像アップロード関連の設定が書き込まれています。結構昔から内容は書き変わっていないので、新しいもので上書きする必要はありません(必要があるときはアナウンスします)。

*4 : h2 aに対しclass="date" が追加されています。

*5 : 過去の日記については、再構築すれば直ります

2007/01/11(木)時刻記法

時刻記法(Version1.03以降対応)

特定の書式で、書き込み時刻(初公開日時)を表示する方法です。*1

[time:%Y/%m/%d]
[time:%H:%M:%S]

などと書くと

[time:%Y/%m/%d]

[time:%H:%M:%S]

と表示されます。

%Y %y %m %d %I %H %M %S %w %s %e %j %k %l %a %p

が使用出来ますが、詳細はstrftimeを参照してください。

またadiary拡張として次のものが使用できます。

%n月表記(桁可変)
%i12時間表記( 0-11)
%L12時間表記(00-11)(2桁)
%J0~24時以降、日付変更時間まで深夜表記
%K0~24時以降、日付変更時間まで深夜表記(2桁)

*1 : この記法は内部的にBase.pm の tm_printf を呼び出しています

2007/01/04(木)adiary + Apache 1.3

adiary + Apache 1.3において、PATH_INFOの解析に失敗することがある不具合を発見しました。mod_rewrite + single ユーザーモードで発生しやすいようです。症状としては、カレンダーで前月に辿れなかったりします。次期バージョンで対応しますが、応急処置的には次のような修正を行ってください。

lib/Satsuki/Base.pm の 1180行目付近に次の一行を追加してください。

$ENV{PATH_INFO} =~ s|//+|/|g;		←追加する行
my $str   =  substr($ENV{PATH_INFO}, 1);
$str      =~ tr/+/ /;
my @pinfo = split('/', $str);

Base.pm:修正したファイルを置いておきます。(Base.pm 52KB)*1

特に問題が発生していない方はこの修正は不要です。

*1 : 修正方法は違いますが問題ありません

追記 2007/01/05

そもそも特定状況下にてパス自動解析の動作が怪しい様子だったのですが、手元でApache1.3環境を用意して色々とテストしてみたものの、不具合が再現できませんでした。*2

*2 : スクリプトからのリンクに'//'が表れてしまうという不具合。発生条件が分かるかたはお知らせください。

2007/01/01(月)あけましておめでとうございます

adiary、これからも少しずつ進化していくと思いますが、何卒よろしくお願いします。改良しつつも頑張って宣伝していきたいと思いますので生温かく見守ってください。

C71でお買い求めになられた方(がいるのかどうか今現在こちらには分からないのですが)、ありがとうございました。今後もクソ真面目な高機能と不釣り合いな遊び心一杯で頑張っていきますので応援よろしくお願いします。

ところで、adiaryたんテーマですけど、↑の(C)があるせいで他の人が使いにくいと思うのは気のせいですか?(笑) >某テーマ作者さま

追伸

日付変更時間処理は、大晦日だけは邪魔ですねー(苦笑)