【Perl】 Smart::Match::noneをより自然言語風に使う
投稿日: / 更新日:
この記事は2年以上前に書かれたものです。情報が古い可能性があります。
Perl 5.10からの新機能であるスマートマッチは、左辺と右辺の値の種類によって、比較の挙動をよしなに変えてくれるという非常に便利な機能ですが、Smart::MatchというCPANモジュールには、このスマートマッチ機能をさらに便利に使うためのヘルパー関数が多数含まれています。
1 2 3 4 5 6 |
(例) ※Smart::Match.pmのドキュメントから引用 given ($foo) { say "We've got a positive number" when positive; say "We've got an array" when array; say "We've got a non-empty string" when string_length(positive); } |
Smart::Matchのヘルパー関数の中で私がよくお世話になるのは、any
やnone
など、リストと比較を行うための関数です。例えば、ある変数の値が別のリストの要素に一つも含まれていないかどうかを確認する場合、以下のようなコードをよく書きます。
1 2 3 4 5 |
use Smart::Match 'none'; ... if ($var ~~ none 'foo', 'bar', 'baz') { ... } |
以上のように、どのような条件判定をしているかがより分かりやすくなります。ただ、ここまで来ると、「もっと自然言語風にしてみたい」という欲求も生まれてきます。上記の例で言えば、$var ~~ none of ...
のように記述できれば嬉しいところです。
上記を実現するため、以下のようなモジュールを書いてみます。なお、引数をカッコなしで渡せるようにするため、プロトタイプを指定しています。ちなみにPerlでは、コードが顔文字のように見えることが往々にしてあります。
1 2 3 4 5 6 7 8 |
package Acme::Language::Natural; use strict; use warnings; use parent 'Exporter'; our @EXPORT_OK = qw/ of /; sub of(@) { @_ } 1; __END__ |
使用例は以下のとおりです。
1 2 3 4 5 6 7 |
[atomitech@node01 perl]$ cat test.pl # test.pl use strict; use warnings; use Smart::Match 'none'; use Acme::Language::Natural 'of'; use Test::More; |
ok(not ‘foo’ ~~ none of ‘foo’, ‘bar’, ‘baz’); ok(not ‘bar’ ~~ none of ‘foo’, ‘bar’, ‘baz’); ok(not ‘baz’ ~~ none of ‘foo’, ‘bar’, ‘baz’); ok( ‘boo’ ~~ none of ‘foo’, ‘bar’, ‘baz’);
done_testing; [atomitech@node01 perl]$ perl test.pl ok 1 ok 2 ok 3 ok 4 1..4
1 |
期待どおりの動作になりました。コードの量が増えて若干面倒になったきらいはあるものの、より自然言語風に記述できるようになりました。以上、あまり有益なTipsではありませんが、スマートマッチに関する簡単な話題をご紹介しました。