Upload
takesako
View
2.776
Download
1
Embed Size (px)
DESCRIPTION
YAPC::Asia 2010 Tokyo Day 2 (Yoshinori TAKESAKO)
Citation preview
2009/04/06 Cybozu University 2
自己紹介
Shibuya Perl Mongers 2代目リーダー
いまここ
2009/04/06 Cybozu University 4
My Parrot
My pretty Parrot (Cockatiel) 可愛的小奧姆
Moshi-moshi ?
My Parrot can say “Hello” when the telephone rang.
另外的 Parrot 算術擅長
Parrot Assembler (PASM)
PASM
set I1, 33set I2, 5mod I3, I1, I2if I3, REMA print "5 is an integer divisor of 33" branch DONE
REMA: print "5 divides 33 with remainder " print I3
DONE: print "¥n" end
33÷5=6、余り2 を計算する
(5 into 33 is 6, remainder 2)
Perl6 の実装方針(最初の戦略)
Parrot
Perl6 を Parrot で書く
Perl5 を Parrot で動くようにする (Ponie Project)
2009/04/06 Cybozu University 8
Perl 5 is alive.
But …
Perl 5 “Hello, world!”
package Earth;sub Greet{
%_=('Y','~');$_='$;=!(Middle
Earth.age~~~<Eart~~~~~~~~~~~~~h
.age)?!(defined$ti~~~~~~~~~~~mez~~~On
e[2])?!(push@time~~~~~~~~~~~~~~~~Zone,loc
~altime())?rotation?~~~~~~~~~~~~~q~~?The Worl
~~d?:q:[¥w]::q=[¥~~~~~~~~~~~~~~~~~d~a-f]=:q?..~~
~~~?:q:.:;"42b3d3~~~~~~~~~~~~~~~~~~~~~728656c6c6f6
~~~~~0277f627c64672~~~~~~~~~~~~~~~~~~~~~b3072796e647
~~~~~~~42b3b3rg7d"=Ym~~~~~~~~~~~~~~~~~~~¥$;~~*¥;p~~~~u
~~~~~~~~~sh@_,$&;bless~~~~~~~~~~~~~~~~~~~~~~~~~$c~~~~~~~
~~~~~~~~~o~ntine~~~~~nt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~s=¥~~~~~~~$~~~~~~~~~~~~~~~~~~~~~~~pangaea~~~~
~~~~~~~~~~~~~~~;{l~~~~~~~~~~~~~~~~~~~~~~~~~~~~ocal@_;local$;
~~~~~~~~~~~~~~~~~="o~~~~~~~~~~~~~~~~~~~~~~~~~cean";$^A=(defi
~~~~~~~~~~~~~~~~~~~n~~~~~~~~~~~~~~~~~~~~~~~~~ed$continents)?
~~~~~~~~~~~~~~~~~~~(vec(~~~~~~~~~~~~~~~~~~~~~~$;, YYsplit(¥'
~~~~~~~~~~~~~~~~~¥',${¥$;}~~~~~~~~~~~~~~~~~~~~~~)%3,YYsplit(
~~~~~~~~~~~~~~~~q??,$;)**2-~~~~~~~~~~~~~~~~~~~~~~(($;=Ytr/oa
~~~~~~~~~~~~~~~~eiu//)**2))=~~~~~~~~~~~~~~~~~~~~~~=28160)?q:
~~~~~~~~~~~~~~~~~.::q?!?:¥'?~~~~~~~~~~~~~~~~~~~~~~¥';}$^A=Ys
~~~~~~~~~~~~~~~~:¥Q.¥E:pack(~~~~~~~~~~~~~~~~~~~~~~¥'h*¥',j
~~~~~~~~~~~~~~~~~oin(q(),~~~~~~~~~~~~~~~~~~~~~~~grep{$_=
~~~~~~~~~~~~~~~~~~Ym,$,,}~~~~~~~~~~~~~~~~~~~~~~~split("
~~~~~~~~~~~~~~~~~",@_~~~~~~~~~~~~~~~~~~~~~~~~~~[0]))
~~~~~~~~~~~~~~~~):e~~~~~~~~~~~~~~~~~~~~~~~~~~~gexe
~~~~~~~~~~~~~~~;$d~~~~~~~~~~~~~~~~~~~~~~~~~~~="s
~~~~~~~~~~~~~~ort~~~~~~~~~~~~~~~~~~~~~~~~~~<=
~~~~~~~~~~~~>,~~~~~~~~~~~~~~~~~~~~~~~~~~YY
~~~~~~~~~~~@_~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~"~~~~~~~~~~~~~~~~~~~';;
s,(~|¥r|¥n|¥s),,g;s.Y.¥x7e.g;
eval};Greet;'the world';
http://www.perlmonks.org/index.pl?node_id=329174 by jbware on Feb 15, 2004 at 21:08 UTC (#329174=obfuscated)
Unreadable
Perl5→読みにくいプログラムを量産し続けるPerl5
Readable
Perl6!読みやすいプログラムを書けるPerl6になる!
Perl 6 では・・・
ね、簡単でしょ?
say "Hello, world!";
2009/04/06 Cybozu University 13
Perl 6on
Parrot
這個 Parrot 能說各種各樣的語言
O’REILLY
NOT’REALLY
2000
Perl6 言語仕様 (language specification)
1. Apocalypse(黙示録)
Larry Wall が Perl6 のデザンについて語る
Perl6 の歴史的な文書(33個のRFCがベース)
2. Exegesis(注釈)
Perl6 を用いたサンプルコードや Perl5 との比較
黙示録を Damian Conway が詳細に解説
3. Synopsis(概要)
Perl6 の最新の言語仕様が書かれている
黙示録のダジェスト版
Why Perl 6 ? (モチベーション)
Perl 5 は・・・場当たり的な拡張を繰り返し
既に Perl5 のコードは理解不能な領域にC でゴリゴリ 職人技 (needs more C hacker)
Perl 6 の目指す方向せめて OO らしく
他の言語で良いところは取り入れよう
後方互換性は無視
コンパラと実行環境の分離Parrot で VM 化
No more C hacker
all your language are belong to us
- Project Perl 6 -
Second System Syndrome (The Mythical Man-Month)
2度目にデザンするシステムは失敗作になりやすい説
1度目のデザンは自分の能力を把握していないので慎重に
3度目のデザンは何が普遍的で何が特殊なものか分かるので正確に作ることができる
しかし2度目のデザンでは、最初のデザンで抑えたゕデゕ・装飾を思い切り詰め込んでしまうので失敗作になりやすい
人月の神話―狼人間を撃つ銀の弾はない
ISBN: 4894716658→ Perl6 は構想10年!
・・・
2005
救世主 Pugs の登場
Pugs = Perl6 User’s Golfing System
Yet another Perl6 implementation
→ Perl6 が動いた!2005/02/06 (1|2)+(3|4)→(4|5|6)
Audrey Tang (唐鳳)
CPAN界隈で有名
PARの作者
1981年生まれ
国籍:台湾
http://en.wikipedia.org/wiki/Audrey_Tang
高橋メソッドを世界に輸出した人
Perl6(Pugs)を Haskell で実装した天才プログラマー
Pugs の拡張性
powered by
Haskell
2010
待望の Perl6 – Rakudo Star リリース!
http://rakudo.org/
http://github.com/rakudo/star/downloads
Get your own Parrot!
34
5秒でわかる Perl 6
メソッドを -> ではなく . で書けるようになった
Perl 5
$obj->method();
Perl 6
$obj.method();
→ これで Perl も立派なOO言語の仲間入り!
36
The End
終了
Perl 6 で失ったもの ~後方互換性~
文字列の連結 .(ドット)→ ~(チルダ)に
Perl5
# メソッド呼び出し
$obj->method();
sub func { return "x"; }
# 文字列の連結
my $a = "str";my $b = $a.func();
Perl6
一時期 ” _ ” という案もあったが…スペース入れるのが面倒
# メソッド呼び出し
$obj.method();
sub func { return "x"; }
# 文字列の連結
my $a = "str";my $b = $a~func();
subst 文字列の置換
Rakudo/bin/ufo より
sub path-to-module-name($path) {$path.subst(/^'lib/'/, '') ¥
.subst(/¥.pm6?$/, '') ¥
.subst('/', '::', :g) ;}
OO
Perl 5
Sigils
$ @ %
配列とハッシュのゕクセス方法が変更
はじめての人にもわかりやすく
変数のプレフゖクス $@% ルールが変更
Perl5 Perl6
my @array = (1, 2, 3);my %hash = ('a'=> 1);
# 配列のメンバにアクセスmy $x = $array[0];
# ハッシュのメンバにアクセスmy $y = $hash{'a'}
my @array = (1, 2, 3);my %hash = ('a'=> 1);
# 配列のメンバにアクセスmy $x = @array[0];
# ハッシュのメンバにアクセスmy $y = %hash{'a'}
Perl 5 の変数(sigils rules)
scalar array hash
------- ------ -------
$s @a %h
$$s $a[0] $h{'?'}
$s->foo ☹ ☹
Perl 6 の変数(Sigils rule)
scalar array hash
------- ------ -------
$s @a %h
$$s @a[0] %h<?>
$s.foo @a.foo %h.foo
☺
() 括弧省略
if, for, while, do ブロックでの(括弧省略)
キータプの量が少なくなった
Perl5 Perl6
if ($a eq $b) {print "a=b¥n";
}
while ($i > 0) {$i--;
}
if $a eq $b {say "a=b";
}
while $i > 0 {$i--;
}
Perl5 Perl6
# スペースなしprint(1+2)*3;
# スペースなしprint(1+2)*3;
(例)
スペースのあり/なしで実行結果が違う
# スペースありprint (1+2)*3;
# スペースありprint (1+2)*3;
→ 実行結果: 3 → 実行結果: 3
→ 実行結果: 3 → 実行結果: 9
Neko operator(範囲演算子)
Damian Conway氏が OSCON2005 で発音
http://www.rubyist.net/~matz/20050803.html
末尾を含まない「..^」
先頭を含まない「^..」
先頭と末尾を含まない「^..^」
Perl6
my @a = (1..^5); # (1,2,3,4)my @b = (1^..5); # (2,3,4,5)my @c = (1^..^5); # (2,3,4)
ネコ演算子って・・・ちょwおまwww
neko operator
^..^
ネコ耳モード♪
Damian Conway 日本の漫画好き?
http://www.amazon.co.jp/dp/4847034864/
49
Please give me!
zip でくれ
使用例:zip でくれ
便利な zip
2つの配列を同時にループ
順番を保存した重複する key と value の表現
Perl5 Perl6
my @key = ("x", "y", "x");my @value = (1, 2, 3);
for (my $i=0; $i<@key; $i++) {my $a = $key[$i];my $b = $value[$i];print "key:$a; value:$b¥n";
}
my @key = ("x", "y", "x");my @value = (1, 2, 3);
for zip(@key,@value) -> $a,$b {print "key:$a; value:$b¥n";
}
実際には Z operator が使える
Rakudo では zip ではなく Z 演算子が実装
(1,2) Z (3,4) (1,3, 2,4)
Rakudo Perl6
my @key = ("x", "y", "x");my @value = (1, 2, 3);
for @key Z @value -> $a,$b {print "key:$a; value:$b¥n";
}
my @key = ("x", "y", "x");my @value = (1, 2, 3);
for zip(@key,@value) -> $a,$b {print "key:$a; value:$b¥n";
}
Piping operators(<==, ==>)
Perl6
@result = map { floor($^x / 2) }
grep { /^ ¥d+ $/ }
@data;
@result <== map { floor($^x / 2) }
<== grep { /^ ¥d+ $/ }
<== @data;
@data ==> grep { /^ ¥d+ $/ }
==> map { floor($^x / 2) }
==> @result;
// 演算子(err 演算子)
左辺が undef のときのみ右辺を評価
// defined or
Perl5 でありがちなバグを回避
0(ゼロ) や ”” (空文字列)の扱い
それぞれ || → or, // → err に対応
Perl5 Perl6
$num = shift @ARGV || 1;
$bar = func() or die;
$num = shift @ARGS // 1;
$bar = func() err die;
// は C言語で単一行コメント(PL/I起源)
/* C comment style */// #include <stdio.h>
必ず Syntax Error になる記号
# Shell - single line comment
# Perl - single line comment
JavaScript // problem
var r = new RegExp(“pattern”);
var r = /pattern/;
これは何?
//
// start a single-line comment.
To specify an empty regular expression,
use /(?:)/
57
Perl 5 Perl 6
正規表現
別の言語
Perl5 正規表現 Perl6 Regex で変わるもの
1. 基本パターン繰り返し *+? と選択 |
2. マッチ演算子文字列のパターンマッチ m//スマートマッチ演算子 ~~文字列の置換 s///
3. 修飾子複数行モード/m 修飾子の廃止文字列の先頭「¥A」末尾「¥z」の廃止スペースとコメントが自由に挿入できるモード/x がデフォルトに単一行モード/s の廃止 /e 修飾子の廃止新しい修飾子の書き方
Perl5 正規表現 Perl6 Regex で変わるもの
4. キャプチャ
キャプチャ括弧(…)と後方参照
キャプチャを伴わない括弧 […]
5. メタキャラクタ
文字クラスの定義 <[a-z]>
定義済み文字クラスの参照 <class>
変数展開 <$var>
文字列 <'string'> のリテラル展開
文字列配列 @strings のリテラル展開
Perl5 正規表現 Perl6 Regex の未来
6. クロージャ
コードの実行 {code}
マッチ失敗 {fail}
繰り返し範囲 **{n..m}
7. ルール
rule
grammar
61
1. 基本パターン
62
繰り返し *+? と選択 |
Perl 5 Perl 6
/x*/ # xが0個以上繰り返し
/y+/ # yが1個以上繰り返し
/z?/ # zが0個以上1個以下
/foo|bar/ # fooまたはbar
/x*/ # == Perl 5
/y+/ # == Perl 5
/z?/ # == Perl 5
/foo|bar/ # == Perl 5
$_ = "aaa bbb ccc foo moo zoo";
if (/aaax*/) { print "ok¥n" }
if (/b+/) { print "ok¥n" }
if (/cccc?/) { print "ok¥n" }
if (/foo|bar|baz/) { print "ok¥n" }
$_ = "aaa bbb ccc foo moo zoo";
if /aaax*/ { say "ok" }
if /b+/ { say "ok" }
if /cccc?/ { say "ok" }
if /foo|bar|baz/ { say "ok" }
63
2. マッチ演算子
文字列のパターンマッチ m//
Perl 5 Perl 6
/pattern/
m/pattern/
m{pattern}
qr/pattern/
$_ = "This is a pen.";
if (/This/) { print "ok¥n" }
if (m/pen/) { print "ok¥n" }
if (m{pen}) { print "ok¥n" }
unless (/not match/) { print "ok¥n" }
if ($_ =~ qr/pen/) { print "ok¥n" }
$_ = "This is a pen.";
if /This/ { say "ok" }
if m/pen/ { say "ok" }
if m{pen} { say "ok" }
unless /not match/ { say "ok" }
if ($_ ~~ rx/pen/) { say "ok" }
/pattern/
m/pattern/
m{pattern}
rx/pattern/ または regex{pattern}
スマートマッチ演算子 ~~
Perl 5 Perl 6
$str =~ /pattern/$str !~ /pattern/
$str ~~ /pattern/$str !~~ /pattern//pattern/ ~~ $str/pattern/ !~~ $str
my $str = "This is a pen.";
if ($str =~ /This/) { print "ok¥n" }
if ($str =~ m/pen/) { print "ok¥n" }
## (m/pen/ =~ $str) とは書けない
if ($str !~ /not match/) { print "ok¥n" }
unless ($str ~~ /not match/) { print "ok¥n" }
my $str = "This is a pen.";
if $str ~~ /This/ { say "ok" }
if $str ~~ m/pen/ { say "ok" }
if m/pen/ ~~ $str { say "ok" }
if $str !~~ /not match/ { say "ok" }
unless $str ~~ /not match/ { say "ok" }
66
3. 修飾子
複数行モード/m 修飾子の廃止
Perl 5 Perl 6
/^ pattern $/m /^^ pattern $$/
my $lines = "aaa¥nbbb¥nccc¥n";
if ($lines =~ /^b/m) { print "ok¥n" }
if ($lines =~ /bb$/m) { print "ok¥n" }
if ($lines =~ /^bbb$/m) {
print "ok¥n";
}
my $lines = "aaa¥nbbb¥nccc¥n";
if $lines ~~ /^^b/ { say "ok" }
if $lines ~~ /bb$$/ { say "ok" }
if $lines ~~ /^^bbb$$/ {
say "ok" ;
}
正規表現の修飾子/mで「^」と「$」のマッチ規則が変わる
文字列の先頭「¥A」末尾「¥z」の廃止
Perl 5 Perl 6
/¥A pattern ¥z/ /^ pattern $/
my $str = "abracadabra";
if ($str =~ /¥Aabra/) { print "ok¥n" }
if ($str =~ /abra¥z/) { print "ok¥n" }
if ($str =~ /¥Aabracadabra¥z/) {
print "ok¥n" ;
}
my $str = "abracadabra";
if $str ~~ /^abra/ { say "ok" }
if $str ~~ /abra$/ { say "ok" }
if $str ~~ /^abracadabra$/ {
say "ok" ;
}
複数行モード/m に影響しないゕンカー記号「¥A」「¥z」
スペースとコメントが自由に挿入できるモード/x がデフォルトに
Perl 5 Perl 6
/ pattern1 # コメントをここに書く
pattern2 pattern3
/x
/ pattern1 # コメントをここに書く
pattern2 pattern3
/
my $str = "abracadabra";
if ( $str =~ / abra # ゕブラca # カ
d abra # ダブラ/x # 終了
) { print "ok¥n" }
if ($str =~ / abra cad abra /x) { print "ok¥n" }
my $str = "abracadabra";
if ( $str ~~ / abra # ゕブラca # カ
d abra # ダブラ/ # 終了
) { say "ok" }
if $str ~~ / abra cad abra / { say "ok" }
スペースのマッチ
Perl 5 Perl 6
/¥ /x
/¥Q ¥E/x
/[ ¥t¥r¥n]/x
/[ ¥t¥r¥n]+/x
/¥ /
/<' '>/
/<space>/
/<ws>/
my $str = "This is¥ta ¥n pen.";
if ($str =~ / This ¥ is /x)
{ print "ok¥n" }
if ($str =~ / This ¥Q ¥E is /x)
{ print "ok¥n" }
if ($str =~ / is [ ¥t¥r¥n] a /x)
{ print "ok¥n" }
if ($str =~ / a [ ¥t¥r¥n]+ pen /x)
{ print "ok¥n" }
my $str = "This is¥ta ¥n pen .";
if $str ~~ / This ¥ is /
{ say "ok" }
if $str ~~ / This <' '> is /
{ say "ok" }
if $str ~~ / is <space> a /
{ say "ok" }
if $str ~~ / a <ws> pen /
{ say "ok" }
単一行モード/s の廃止
Perl 5 Perl 6
/./s # どんな文字(改行を含む)
/./ # どんな文字も(改行は除く)
/[¥x0D¥x0A]|¥x0D¥x0A/
/./ # 改行を含むどんな文字
/¥N/ # 改行以外のどんな文字も
/¥n/ # どんな端末の改行にもマッチ
my $c = '/************************ This is a C comment ************************/#include <stdio.h>/* first */main() { printf("C"); }';
if ($c =~ m/(¥/¥*.+?¥*¥/)/) {if ($1 eq "/* first */") { print "ok¥n" }
}if ($c =~ m/(¥/¥*.+?¥*¥/)/s) {
my $lines = $1;if ($lines =~ /comment/) { print "ok¥n" }
}
my $c = '/************************ This is a C comment ************************/#include <stdio.h>/* first */main() { printf("C"); }';
if $c ~~ m{( ¥/¥* ¥N+? ¥*¥/ )} {if $0 eq "/* first */" { say "ok" }
}if $c ~~ m{( ¥/¥* [.|¥n]+? ¥*¥/ )} {
my $lines = $0;if $lines ~~ /comment/ { say "ok" }
}
/e 修飾子の廃止 どこでも {code}
Perl 5 Perl 6
s/pattern/code/e s/pattern/{code}/
sub cm2inch {
my ($cm) = @_;
sprintf('%.01f-inch', $cm / 6.5);
}
my $floppy = "3.5-inch FDD";
if ($floppy =~ s/(¥d+¥.¥d+)-inch/{ sprintf('%.02f-cm',
$1 * 6.5) }/ex) {
if ($floppy eq "22.75-cm FDD") { print "ok¥n" }
if ($floppy =~ s/(¥d+¥.¥d+)-cm/{ &cm2inch($1) }/ex) {
if ($floppy eq "3.5-inch FDD") { print "ok¥n" }
}
}
sub cm2inch($cm) {
sprintf('%.01f-inch', $cm / 6.5);
}
my $floppy = "3.5-inch FDD";
if $floppy ~~ s/(¥d+¥.¥d+)-inch/{ sprintf('%.02f-cm', $0 * 6.5) }/ {
if $floppy eq "22.75-cm FDD" { say "ok" }
if $floppy ~~ s/(¥d+¥.¥d+)-cm/{ &cm2inch($0) }/ {
if $floppy eq "3.5-inch FDD" { say "ok" }
}
}
cf. Acme::Hyde(単位変換) on CPAN
新しい修飾子の書き方
Perl 5 Perl 6
m/pattern/i
s/pattern/replace/ig
m/:i pattern/
s:g/pattern/replace/
my $imas = "とかしつくして";
if ($imas =~ s/し/ち/g) {
if ($imas eq "とかちつくちて") {
print "ok¥n";
}
}
my $imas = "とかしつくして";
if $imas ~~ s:g/し/ち/ {
if $imas eq "とかちつくちて" {
say "ok";
}
}
74
4. キャプチャ
キャプチャ括弧(…)と後方参照
Perl 5 Perl 6
(…)〃¥1〃¥2〃¥3… (…)〃$0〃$1〃$2…
my $str = "abracadabra";
if ($str =~ /(a)br¥1c/) { print "ok¥n" }
if ($str =~ /(ab)racad$1ra/) { print "ok¥n" }
if ($str =~ /(a)(b)r$1c$2d$2$2ra/) {
print "ok¥n" ;
}
if ($1 eq "a") { print "ok¥n" }
if ($2 eq "b") { print "ok¥n" }
my $str = "abracadabra";
if $str ~~ /(a)br$0c/ { say "ok" }
if $str ~~ /(ab)racad$0ra/ { say "ok" }
if $str ~~ /(a)(b)r$0c$0d$0$1ra/ {
say "ok" ;
}
if ($0 eq "a") { say "ok" }
if ($1 eq "b") { say "ok" }
日本円¥廃止
ドル$決済でゼロスタート
括弧(…)でキャプチャして、同じ正規表現内で後方参照する
【覚え方】
キャプチャを伴わない括弧 […]
Perl 5 Perl 6
(?:pattern) [pattern]
my @domain = ( "shibuya.pm.org",
"shibuya.pl" ,
"shibuyajs.org" ,
);
for (@domain) {
if (/^(¥w+)(?:¥.|-)?(js|pm|pl)(?:.org)?$/)
{
print "Hello, $1 $2 !¥n";
}
}
my @domain = ( "shibuya.pm.org",
"shibuya.pl" ,
"shibuyajs.org" ,
);
for @domain {
if /^(¥w+) [¥.|¥-]? (js|pm|pl) [.org]? $/ {
say "Hello, $0 $1 !";
}
}
ドメン名からコミュニテゖ名を判断し "Hello, shibuya pm !" と挨拶する
77
5. メタキャラクタ
文字クラスの定義 <[a-z]>
Perl 5 Perl 6
[abc]
[a-z]
[^xyz]
[B-Y]
<[abc]>
<[a-z]>
<-[xyz]>
< <[A-Z]> - <[AZ]> >
my @files = ("Jcode.pm", "Encode.pm", "jcode.pl");
foreach (@files) {
if (/ ( (?:J|En|j) code ¥. p[ml]) /x ) {
if ($_ eq $1) { print "ok¥n" }
}
}
my @files = ("Jcode.pm", "Encode.pm", "jcode.pl");
for @files {
if / ( [J|En|j] code ¥. p<[ml]> ) / {
if $_ eq $0 { say "ok" }
}
}
"Jcode.pm", "Encode.pm", "jcode.pl" のどれにもマッチする正規表現
文字クラスの定義 <[a-z]>
Perl 5 Perl 6
¥x20 # 空白1文字¥s+ # 連続したスペース¥. # ドット
[[:digit:]] # [0-9][[:upper:]] # [A-Z][[:lower:]] # [a-z][[:alpha:]] # [A-Za-z][[:alnum:]] # [A-Za-z0-9]
<space> # 空白1文字<ws> # 連続したスペース<dot> # ドット ※ <lt>, <gt><digit> # 数字<upper> # 英大文字<lower> # 英小文字<alpha> # ゕルフゔベット<alnum> # ゕルフゔベットと数字
$_ = "123 abc ¥t 456 ijk ¥t 789 XYZ";
if (/ ([0-9]+) ¥ ([A-Za-z]+) /x) {
if ($1 eq "123" && $2 eq "abc") { print "ok¥n" }
}
if (/ ([A-Za-z]+) ¥s+ ([0-9]+) /x) {
if ($1 eq "abc" && $2 eq "456") { print "ok¥n" }
}
$_ = "123 abc ¥t 456 ijk ¥t 789 XYZ";
if / (<digit>+) ¥ (<alpha>+) / {
if $0 eq "123" && $1 eq "abc" { say "ok" }
}
if / (<alpha>+) <ws> (<digit>+) / {
if $0 eq "abc" && $1 eq "456" { say "ok" }
}
変数展開 <$var>
Perl 5 Perl 6
/ $var /x / <$var> /
my $var = "(This|That) is a (pen|book)";
my $text1 = "This is a pen";
my $text2 = "That is a book";
if ($text1 =~ /$var/) {
print "ok¥n";
}
if ($text2 =~ /$var/) {
print "ok¥n";
}
my $var =
"(This|That)<space>is<space>a<space>(pen|book)";
my $text1 = "This is a pen";
my $text2 = "That is a book";
if ($text1 ~~ m/<$var>/) {
say "ok";
}
if ($text2 ~~ m/<$var>/) {
say "ok";
}
文字列 <'string'> のリテラル展開
Perl 5 Perl 6
¥Q$var¥E
¥Qstring¥E
¥$¥Qstring¥E
$var
<'string'>
<'$string'>
my $err = "Can't locate Boofy.pm in ¥@INC";
my $soozy = "Boofy.pm";
if ($err =~ /¥Q$soozy¥E/x) {
print "ok¥n";
}
if ($err =~ /¥@INC/x) {
print "ok¥n";
}
my $err = "Can't locate Boofy.pm in ¥@INC";
my $soozy = "Boofy.pm";
if $err ~~ /$soozy/ {
say "ok";
}
if $err ~~ /<'@INC'>/ {
say "ok";
}
文字列配列 @str のリテラル展開
Perl 5 Perl 6
$target ~~ / (?: ¥Q$str[0]¥E |
¥Q$str[1]¥E | … ) /x
$target ~~ / @str /
my @str = ("orz", "OTL", "_|~|-O");
my $food = "pasta mista, peperini,
capellini tagliati,
orzi piccoli, stelline.";
if ($food =~ /(?: ¥Q$str[0]¥E
| ¥Q$str[1]¥E
| ¥Q$str[2]¥E )/x)
{
print "ok¥n";
}
my @str = ("orz", "OTL", "_|~|-O");
my $food = "pasta mista, peperini,
capellini tagliati,
orzi piccoli, stelline.";
# Rakudo では未実装っぽい
if $food ~~ / @str / {
say "ok";
}
83
6. クロージャ
どこでもコード実行 {code}
Perl 5 Perl 6
/pat(?{code})tern/ # 埋め込みコード
/pat(??{retcode})tern/ # 動的正規表現
/pat{code}tern/
/pat<{retcode}>tern/
my $text = "pattern";
$text =~ m/pat(?{print "ok¥n"})tern/;
if ($text =~ m/pat(??{lc("TER")})n/) {
print "ok¥n";
}
my $text = "pattern";
$text ~~ m/pat{say "ok"}tern/;
if $text ~~ m/pat<{lc("TER")}>n/ {
say "ok";
}
どこでもクロージャ{...}
マッチ失敗 {fail}
Perl 5 Perl 6
/ (...) {fail} /
my $x = qr/(25[0-5]|(?:2[0-4]|1[0-9]|[1-9])?[0-9])/;
for (0..255) {
/^($x)$/;
}
my $addr = "192.168.1.33";
if ($addr =~ /^($x¥.$x¥.$x¥.$x)$/) {
print "ok¥n";
}
my $x = / (¥d+) {fail if $0 > 255} /;my $ipv4 = /^ $x ¥. $x ¥. $x ¥. $x $/;my $addr = "192.168.1.33";if $addr ~~ /$ipv4/ {
say "ok";}
正規表現のクロージャ内で fail を呼ぶと〃現在のキャプチャ内のマッチに失敗させることができる。これを応用すると、正規表現中に複雑な計算式やプログラムを組み込んでパターンマッチさせられる。
【例】 IPアドレスをチェックする正規表現
[これは便利]
86
7. ルール
正規表現のラブラリ化
Perl 6 Rules & Grammars
grammar Inventory {
regex product { ¥d+ }
regex quantity { ¥d+ }
regex color { ¥S+ }
regex description { ¥N* }
regex TOP { ^^ <product> ¥s+ <quantity> ¥s+
[
| <description> ¥s+ '(' ¥s* <color> ¥s* ')'
| <color> ¥s+ <description>
]
$$
}
Inventory.parse($source_lines);
Example
Target strings Perl 6 code# lib/MyProject/Test.pm
package MyProject::Test;use Test::Base -Base;use MyProject;…package MyProject::Test::Filter;use Test::Base::Filter -base;sub my_filter {
return MyProject->do_something(shift);}
# t/sample.tuse MyProject::Test;
plan tests => 1 * blocks;
run_is input => 'expected';
sub local_filter {s/my/your/;
}
__END__
=== Test one (the name of the test)--- input my_filter local_filtermyinputlines--- expectedexpectedoutput=== Test twoThis is an optional descriptionof this particular test.--- input my_filterotherinputlines--- expectedother expectedoutput
grammar Test::Base::Spec {
rule spec { <block>* }
rule block {<head><comment><section>*
}
rule head {<block_delim> [ <sp>+ <name> ]? ¥n
}
rule comment {[ <!section_delim> <line> ]*
}
rule section {<section_delim><sp>+ <name><sp>+ [ <filter> <sp>+ ]*[ ':' <data> ¥n | ¥n <chunk> ]
}
rule block_delim { ¥=¥=¥= }rule section_delim { ¥-¥-¥- }
rule line { ¥N* ¥n }rule name { ¥N* }rule data { ¥N* }rule filter { ¥S+ }
rule chunk {[ <!block_delim> <!section_delim> <line> ]*
}
}
http://search.cpan.org/~ingy/Test-Base/lib/Test/Base.pm
89
Named capture など
まだまだ紹介しきれない
便利な機能がいっぱい!
90
さらに詳しく
参考URL
Perl 6 rules - Wikipedia http://en.wikipedia.org/wiki/Perl_6_rules
perl6: Apocalypse 5: Pattern Matching (Larry Wall)
http://dev.perl.org/perl6/doc/design/apo/A05.html
perl6: Synopsis 5: Regexes and Rules (Damian Conway)
http://dev.perl.org/perl6/doc/design/syn/S05.html
Perl 6 FAQ - Regexes and Grammars http://www.programmersheaven.com/2/Perl6-FAQ-Regex
Perl6::Rules - Implements (most of) the Perl 6 regex syntax http://search.cpan.org/~dconway/Perl6-Rules/Rules.pm
日本語 Perl6 Rules(新たな正規表現)
http://www9.ocn.ne.jp/~ymt/perl6/rules.html
92
Have fun!
Enjoy Perl 6
Perl 6 正規表現プログラミング楽土入門