黒魔術を読み解く

Perl初心者のためのPerlノートです!

HTML/ CSS/ CGI-Perl/ JavaScript/ JavaApplet/ AccessUp/ Internet/ EnglishLearn/ ちゃいちゃん天使/ 天使メッセージ/ 飯田ワールド/ 結城ワールド/ プロフィール/ WEB相談室/ WEBアンテナ/ WEBリーダー/ 燈明日記/ yahoo

◆ はじめに

本ページは、私がPerlを習得した時(いや習得中)のノートです。

ごく普通の言語(COBOL,C,Java,VB等)を知っている人が、Perlをやり始めるといろいろと悩むことがあります。

それは、

です。

本ページは、そのようなハードルを一つ一つクリアにしていけたらと思います。

そして、本ページが何かのお役に立てれば幸いです。では、ごゆっくりご覧ください。

尚、ご感想、ご意見、誤字、脱字、間違い等がありましたら遠慮なくPerlノート掲示板へご指摘ください。

◆ サイト最新情報

◆ コンテンツ

2009-06-14 黒魔術を読み解く

久々に弾さんのブログを見て、以下のソースが理解できなかったので、調べてみました。

折角なので、調べたことをメモしときます。

#!/usr/bin/perl
use strict;
use warnings;
{
    no warnings 'redefine';
    *CORE::GLOBAL::glob = sub{
        my $expr = shift;
        warn $expr;
        $expr =~ s{
            \A(.*?)~~(.*?)(\^\.)(\.\^?)(.*?)
        }{
            my $num = eval $1;
            my $min = $2;
            my $lt0  = length($3) == 1 ? '<=' : '<';
            my $lt1  = length($4) == 1 ? '<=' : '<';
            my $max = $5;
            qq($min $lt0 $num && $num $lt1 $max);
        }emsx;
        warn $expr;
        eval $expr;
    };
}
local $\="\n";
print "OK" if     <length('^..^') ~~ 3^..^5>;
print "OK" unless <length('^..^') ~~ 0^..^3>;
http://blog.livedoor.jp/dankogai/archives/51222364.html

no warnings 'redefine';

関数を再定義する時のワーニングを抑制する。


*CORE::GLOBAL::glob = sub{

組み込みglob関数をオーバーライド(関数再定義)しています。


my $expr = shift;

glob関数の第1引数を$exprへ代入しています。


warn $expr;

標準エラー出力へ$exprの内容を出力しています。


$expr =~ s{ \A(.*?)~~(.*?)(\^\.)(\.\^?)(.*?) }{ ・・・ }emsx;

\Aは、常に文字列の先頭にのみマッチします。

ちなみに、^ では文字列中に埋め込まれた改行の直後にもマッチしてしまいます。

後の正規表現は、ちょっと問題あり・・・かも(最後の方で説明します)。


e修飾子

e修飾子は、s{}{} の右側を式とみなして実行します。


m修飾子

m修飾子は、文字列を複数行として扱います。


s修飾子

s修飾子は、ドット(.) が改行にも一致するようにします。


x修飾子

x修飾子は、パターン内のスペースを無視し、コメントを入れられるようにします。


my $num = eval $1;

今回は、length('^..^')の実行結果が$numに入ります。


my $min = $2;

今回は、3^..^5 の3が$minに入ります。


my $lt0 = length($3) == 1 ? '<=' : '<';

3項演算で、今回は3^..^5 の『^.』が$3入り、lengthは文字列『^.』なので2なり、$lt0には '<' が入ります。


my $lt1 = length($4) == 1 ? '<=' : '<';

3項演算で、今回は3^..^5 の『.^』が$4入り、lengthは文字列『.^』なので2なり、$lt1には '<' が入ります。


my $max = $5;

今回は、3^..^5 の5が入ります。


qq($min $lt0 $num && $num $lt1 $max);

文字列 "$min $lt0 $num && $num $lt1 $max" と等価です。

しかし、単なる文字列でどこにも代入していない。

たぶん、最後に評価したものが現状のもを置換して、$exprに格納されるのかな・・・たぶん。


warn $expr;

標準エラー出力へ$exprの内容を出力しています。


eval $expr;

今回は、$exprには、文字列 "$min $lt0 $num && $num $lt1 $max" が格納されていて、eval(実行)します。


local $\="\n";

print文の最後に"\n"が付加されるようです。


正規表現がおかしい?

調べていて気がついたのですが正規表現が間違っているような感じです。

\A(.*?)~~(.*?)(\^\.)(\.\^?)(.*?)

\A(.*?)~~(.*?)(\^\.|\.)(\.\^|\.)(.*)

ではないでしょうか?

3..5

3..^5

の場合に置換しないのです。


ネコ演算子(^..^)

そもそもネコ演算子は、Perl6で実装されるとのことで、Perl5の範囲演算子の機能拡張版です。

3..5は (3,4,5)のリスト

3^..5は、(4,5)のリスト

3..^5は、(3,4)のリスト

3^..^5は、(4)のリスト

◆ おすすめ Perl本

■ 続・初めてのPerl 改訂版

『初めてのPerl』の次ぎに読むと吉です。

結構いいですが・・・、初心者にはちょっと難しいかもです。

■ 結城浩のPerlクイズ

この本には、ちゃいちゃんパパの小話しが載っています(謎)。

ある程度、Perlを理解している人には、たまらない内容になっています。さすが結城先生だな!

結城浩のPerlクイズ

■ 新版Perl言語プログラミングレッスン入門編

実は、私はまだ読んでいませんが、結城先生の本なので良くないはずがありません。

新版Perl言語プログラミングレッスン入門編

■ CGI&Perlポケットリファレンス (Pocket reference)

この本は、非常に役に立ちます。ちょっと調べるのに最適です。サンプルも説明も的を射ています。

CGI&Perlポケットリファレンス (Pocket reference)

■ Perlベストプラクティス

一読の価値有りだと思います。

Perlベストプラクティス

■ プログラミングPerl〈VOLUME1〉

ご存知、Perl本の聖書、ラクダ本(上)です。

■ プログラミングPerl〈VOLUME2〉

ご存知、Perl本の聖書、ラクダ本(下)です。

◆ おわりに

最後に、本ページが、何かのお役に立てれば幸いです。

尚、ご感想、ご意見、誤字、脱字、間違い等がありましたら遠慮なくPerlノート掲示板へご指摘ください。

HTML/ CSS/ CGI-Perl/ JavaScript/ JavaApplet/ AccessUp/ Internet/ EnglishLearn/ ちゃいちゃん天使/ 天使メッセージ/ 飯田ワールド/ 結城ワールド/ プロフィール/ WEB相談室/ WEBアンテナ/ WEBリーダー/ 燈明日記/ yahoo