このサイトはblogban.net(2016年3月にドメイン有効期限切れで閉鎖)のログを保管しているサイトです。
各投稿の権利は当時の投稿者に帰属します。
なお、本サイトでは発信者情報は一切保存しておりませんのでご了承下さい。
過去ログ倉庫ですので書き込みはできません。


なお当時のblogbanの規約に基づき本サイトのログはアフィリエイトブログへの転載を全面的に禁止します。


専ブラ対応済みです。このURLをそのまま外部板登録すると閲覧できます。


お問い合わせはこちらまで



■掲示板に戻る■ 全部 1- 101- 最新50 [PR]ぜろちゃんねるプラス[PR]  

Perlについて

1 :名無しさん名前募集中。。。:2013/07/07(日) 15:07:34.53 ID:j0iarVna0
TMTOWTDI = There's more than one way to do it.
やり方はひとつじゃない。

じゃあ、Perlについて語ろうか。

Perl Download
http://www.perl.org/get.html

60 :名無しさん名前募集中。。。:2013/07/23(火) 19:00:54.63 ID:RpxHE7560
9.1 s///を使って置換を行なう

use 5.016;
use warnings;

$_ = "Say it ain't so, Joe!";

s/Joe/Bernie/;
say;

結果
Say it ain't so, Bernie!

perlop - Perl の演算子と優先順位 正規表現のクォート風の演算子
http://perldoc.jp/docs/perl/5.16.1/perlop.pod#Regexp32Quote-Like32Operators

> s/PATTERN/REPLACEMENT/msixpodualgcer
> 文字列中でパターンを検索し、もし見つかれば、置換テキストで置き換え、
> 置換した数を返します。 見つからなければ、偽 (具体的には、空文字列) を返します。
> /r (非破壊) オプションが使われると、文字列のコピーに対して置換が行われ、
> 置換された数ではなく、置換が行われたかどうかにかかわらずこのコピーが
> 返されます。 /r が使われた場合、元の文字列は決して変更されません。
> コピーは、たとえ入力がオブジェクトや tie された変数でも、常に
> プレーンな文字列です。

perlop - Perl の演算子と優先順位 拘束演算子
> 二項演算子の "!~" を非破壊置換 (s///r) や変換 (y///r) で使うと
> 文法エラーとなります。

/rを使うと式に組み込みやすくなるので、高階関数と相性が良いです。

use 5.016;
use warnings;

my ($source, $copy);

$source = 'Hello, World!';
$copy = $source =~ s/World/Perl/;
say $copy;

$source = 'Hello, World!';
$copy = $source =~ s/World/Perl/r;
say $copy;

結果
1
Hello, Perl!

9.1.1 /gによるグローバルな置換

s///gで可能な限り全てを置き換えます。

61 :名無しさん名前募集中。。。:2013/07/23(火) 19:05:13.55 ID:RpxHE7560
9.2 split演算子

split
http://perldoc.jp/func/split
> split /PATTERN/,EXPR,LIMIT
> split /PATTERN/,EXPR
> split /PATTERN/
> split
> 文字列 EXPR を文字列のリストに分割して、リストコンテキストではそのリストを
> 返し、スカラコンテキストではリストの大きさを返します。
> PATTERN のみが与えられた場合、EXPR のデフォルトは $_ です。

use 5.016;
use warnings;

$_ = ' a b c ';
say join(':', split);
say join(':', split ' ');
say join(':', split / /);
say '';
$_ = '1,2,3,,';
say join(':', split /,/);
say join(':', split /,/, $_, 2);
say join(':', split /,/, $_, -1);
say '';

結果
a:b:c
a:b:c
::a::b:c

1:2:3
1:2,3,,
1:2:3::

62 :名無しさん名前募集中。。。:2013/07/23(火) 19:05:31.91 ID:RpxHE7560
use 5.016;
use warnings;

# line count ...?

$_ = <<'EOF';
a
b
c

EOF

say scalar split /^/;
say scalar split /$/m;
say scalar split /\n/;
say scalar split /\n/, $_, -1;

結果
4
5
3
5

63 :名無しさん名前募集中。。。:2013/07/23(火) 19:16:10.18 ID:RpxHE7560
コピペして、今更ながら、スペースが潰れるのを思い出した……。

$_ = ' a b c ';

($_ = '..a..b.c..') =~ s/\./ /g;

64 :名無しさん名前募集中。。。:2013/07/24(水) 19:00:31.20 ID:usP7rrSD0
9.3 join関数

join

> join EXPR,LIST
> LIST の個別の文字列を、EXPR の値で区切って 1 つの文字列につなげ、
> その文字列を返します。
> "split" と違って、"join" は最初の引数にパターンは取れないことに
> 注意してください。 "split" と比較してください。

use 5.016;
use warnings;

my @array = ('a' .. 'c');

say join('', @array);
say join('..', @array);

say join(/^/, @array); # say join(scalar($_ =~ /^/), @array);

結果
abc
a..b..c
a1b1c

標準エラー出力
/^/ should probably be written as "^" at ... line 9.
Use of uninitialized value $_ in pattern match (m//) at ... line 9.

65 :名無しさん名前募集中。。。:2013/07/24(水) 19:01:41.13 ID:usP7rrSD0
9.4 m//をリストコンテキストで使う

perlop - Perl の演算子と優先順位 正規表現のクォート風の演算子
http://perldoc.jp/docs/perl/5.16.1/perlop.pod#Regexp32Quote-Like32Operators

> /gオプションが使われなかった場合、リストコンテキストでのm//は
> パターンの中の括弧で括られた部分列にマッチしたもので構成されるリストを
> 返します。 これは、($1, $2, $3, ...) ということです。 (この場合、
> $1 なども設定されます。 この点で Perl 4 の動作と違っています。)
> パターンに括弧がない場合は、返り値は成功時はリスト (1) です。
> 括弧のあるなしに関わらず、失敗時は空リストを返します。

> /g 修飾子は、グローバルなパターンマッチを指定するもので、 文字列の中で
> 可能な限りたくさんマッチを行ないます。 この動作は、コンテキストに依存します。
> リストコンテキストでは、正規表現内の括弧付けされたものにマッチした
> 部分文字列のリストが返されます。 括弧がなければ、パターン全体を
> 括弧で括っていたかのように、 すべてのマッチした文字列のリストが返されます。

リストコンテキストを使うと以下のように書けるようになりますが、
スカラコンテキストが使われることが多いので、あまり見かけないように思います。

if (my ($word, $digits) = /(\w+) (\d+)/){
...
}

9.5.1 欲張りでない量指定子

perlre - Perl 正規表現 量指定子
http://perldoc.jp/docs/perl/5.14.1/perlre.pod#Quantifiers
> デフォルトでは、パターンで行われる量指定は"貪欲"です; つまりそれは
> パターンの残りの部分が可能な範囲で、 (始めた地点から)可能な限り多くを
> 先にあるパターンでマッチングさせます。 もし最小回数でのマッチングを
> 行いたいのであれば、量指定子の後ろに "?" を続けます。
> 意味は変更されずに「貪欲さ」だけを変更できます:

> *? 0 回以上の貪欲でないマッチング
> +? 1 回以上の貪欲でないマッチング
> ?? 0 回または 1 回の貪欲でないマッチング
> {n}? ちょうど n 回の貪欲でないマッチング (冗長)
> {n,}? n 回以上の貪欲でないマッチング
> {n,m}? n 回以上 m 回以下の貪欲でないマッチング

66 :名無しさん名前募集中。。。:2013/07/24(水) 19:04:09.90 ID:usP7rrSD0
10.1 unless制御構造

偽の時にコードブロックを実行するif。
else節を伴う場合、ifに書き直します。

10.2 until制御構造

偽の時にコードブロックを実行するwhile。
使いません。

10.3 式修飾子

文修飾子(statement modifier)。

perlsyn - Perl の文法 文修飾子
http://perldoc.jp/docs/perl/5.16.1/perlsyn.pod#Statement32Modifiers
> 任意の単純文には、一つ の修飾子を終端のセミコロンの直前(もしくは
> ブロックの終端の直前)に付けることができます。 使うことのできる修飾子は
> 以下の通りです。

> if EXPR
> unless EXPR
> while EXPR
> until EXPR
> for LIST
> foreach LIST
> when EXPR

> 修飾子に引き続く EXPR は「条件」として参照されます。
> その真偽値が修飾子の振る舞いを決定します。

> 注意: (my $x if ... のような) 条件構造やループ構造で修飾された
> my state,our 文の振る舞いは 未定義 です。 my 変数の値は undef かも
> 知れませんし、以前に代入された値かも 知れませんし、その他の如何なる値の
> 可能性もあります。 この値に依存してはいけません。

そのままでは警告さえも出ませんが、perlcriticで検出可能です。

use 5.016;
use warnings;
use Perl::Critic qw(critique);

print critique($0);

my $v = 0xDEAD if 0;
say $v // '(undef)'; # !?

結果(例)
Variable declared in conditional statement at line 7, column 1. Declare variables outside of the condition.
(undef)

(プログラムに埋め込みましたが、通常はコマンドラインかテストモジュールから
perlcriticを使います)。

67 :名無しさん名前募集中。。。:2013/07/24(水) 19:06:59.75 ID:usP7rrSD0
10.4 裸のブロック構造

主に、レキシカルスコープを提供するために使います。

10.5 オートインクリメント

C言語のオートインクリメント、デクリメントと同じようにふるまいます。

perlop - Perl の演算子と優先順位 インクリメントとデクリメント
http://perldoc.jp/docs/perl/5.16.1/perlop.pod#Auto-increment32and32Auto-decrement
> C と同様、Perl は いつ 変数がインクリメントまたはデクリメントされるかは
> 定義されません。 値が返される前か後のどこかで行われる、
> ということだけがわかります。 これは、同じ文である変数を 2 回修正すると、
> 振る舞いが未定義になることを 意味します。 以下のような文は避けてください:

> $i = $i ++;
> print ++ $i + $i ++;


10.7.1 foreachとforの秘められた関係

perlsyn - Perl の文法 foreach ループ
http://perldoc.jp/docs/perl/5.16.1/perlsyn.pod#Foreach32Loops
> foreach は実際には for の同義語なので、どちらでも使えます。

Cスタイルのfor(;;)は避けましょう。

68 :名無しさん名前募集中。。。:2013/07/24(水) 19:07:54.43 ID:usP7rrSD0
10.8 ループを制御する

do - while の罠

perlsyn - Perl の文法 基本ブロック
http://perldoc.jp/docs/perl/5.16.1/perlsyn.pod#Basic32BLOCKs
> ブロックから脱出するためやブロックの再スタートのために 任意のループ制御文を
> 使うことができます。 (これは eval{}、sub{}、 さらに一般的な認識とは異なり
> ループではない do{} ブロックに対しては 真ではない ということに
> 注意してください。)

perlsyn - Perl の文法 文修飾子
http://perldoc.jp/docs/perl/5.16.1/perlsyn.pod#Statement32Modifiers
> 後述するループの制御文は、修飾子がループラベルを取らないために
> この構造文では 動作しない ということにも注意してください。 申し訳ない。
> こういった場合に対処するのに別のブロックを内側に入れたり(next の場合)、
> 別のブロックで囲む(last の場合)という方法が常に使えます。

> do {{
> next if $x == $y;
> # do something here
> }} until $x++ > $z;

>last の場合は、もっと念入りにする必要があります:

> LOOP: {
> do {
> last if $x = $y**2;
> # do something here
> } while $x++ <= $z;
> }

更に、do{}while();形式では、doブロックで作成された変数をwhileの評価式では使えません。

69 :名無しさん名前募集中。。。:2013/07/24(水) 19:08:10.95 ID:usP7rrSD0
perlsyn - Perl の文法 複合文
http://perldoc.jp/docs/perl/5.16.1/perlsyn.pod#Compound32Statements
> LABEL while (EXPR) BLOCK
> LABEL while (EXPR) BLOCK continue BLOCK

> LABEL until (EXPR) BLOCK
> LABEL until (EXPR) BLOCK continue BLOCK

> LABEL for (EXPR; EXPR; EXPR) BLOCK
> LABEL for VAR (LIST) BLOCK
> LABEL for VAR (LIST) BLOCK continue BLOCK

> LABEL foreach (EXPR; EXPR; EXPR) BLOCK
> LABEL foreach VAR (LIST) BLOCK
> LABEL foreach VAR (LIST) BLOCK continue BLOCK

> LABEL BLOCK
> LABEL BLOCK continue BLOCK

特殊なブロック

perlmod - Perl のモジュール (パッケージとシンボルテーブル)
BEGIN, UNITCHECK, CHECK, INIT, END
http://perldoc.jp/docs/perl/5.16.1/perlmod.pod#BEGIN44UNITCHECK44CHECK44INIT32and32END
> 5 つの特殊な名前のついたコードブロックは、Perl プログラムの開始時および
> 終了時に実行されます。 それは BEGIN, UNITCHECK, CHECK, INIT, END ブロックです。

70 :名無しさん名前募集中。。。:2013/07/24(水) 19:10:48.54 ID:usP7rrSD0
10.10 論理演算子

perlop - Perl の演算子と優先順位 論理積
http://perldoc.jp/docs/perl/5.16.1/perlop.pod#Logical32And
> 二項演算子の "and" は両側の式の論理積を返します。 これは、優先順位が
> ずっと低いことを除けば && と等価です。 つまり、これも短絡演算を行ない、
> 右側の式は左側の式が 「真」であった場合にのみ評価されます。

perlop - Perl の演算子と優先順位 論理和と排他論理和
http://perldoc.jp/docs/perl/5.16.1/perlop.pod#Logical32or32and32Exclusive32Or
> 二項演算子の "or" は両側の式の論理和を返します。 これは、優先順位が
> ずっと低いことを除いて || と等価です。 これはフローを制御するのに有用です:

> print FH $data or die "Can't write to FH: $!";

> つまり、これも短絡演算を行ない、右側の式は左側の式が 「偽」であった
> 場合にのみ評価されます。 優先度の関係で、これを || 演算子の置き換えに
> 使うのは慎重に 避けなければなりません。

10.10.3 部分評価演算子を使って制御構造を実現する

左項の評価結果によって、右項を評価するかどうかが決まる演算は、
短絡演算(short-circuit evaluation)と呼ばれたり、演算子が
部分評価演算子(partial-evaluation operator)と呼ばれたりします。

... or die;
... or next;

などの制御を行う部分で使います。

71 :名無しさん名前募集中。。。:2013/07/24(水) 23:33:58.87 ID:JewgDfrr0
Rubyスレは無いですかそうですか

72 :名無しさん名前募集中。。。:2013/07/25(木) 19:14:21.55 ID:WhVb7wVz0
>>71
まあ、立ててみては?

73 :名無しさん名前募集中。。。:2013/07/25(木) 19:36:50.55 ID:WhVb7wVz0
11.1 モジュールを探す

search CPAN http://search.cpan.org/
Meta CPAN https://metacpan.org/

11.2 モジュールをインストールする

perlfaq8 - システムとの相互作用 モジュールを CPAN からインストールするには?
http://perldoc.jp/docs/perl/5.14.1/perlfaq8.pod#How32do32I32install32a32module32from32CPAN63
> 最も単純な方法は、Perl と同梱されている cpan コマンドを使って、
> この仕事を してくれる CPAN モジュールを入手することです。
> インストールするモジュールの一覧を与えます:
>
> $ cpan IO::Interactive Getopt::Whatever

> 全ての依存を自分で解決して、配布を自分自身でインストールしてみたい場合は、
> 二つのビルド方法のどちらかに従います。
> Makefile.PL を使う配布では:
>
> $ perl Makefile.PL
> $ make test install
>

> 一部の配布ではBuild.PL を使う配布では:
>
> $ perl Build.PL
> $ ./Build test
> $ ./Build install

> ライブラリはその他のサードパーティのコードへのリンクが
> 必要であったり、ビルドとインストールの手順がもっと複雑な場合もあります。
> 見付かった README や INSTALL ファイルをチェックしてください。

cpan
http://perldoc.perl.org/cpan.html

cpanm

App::cpanminus
http://search.cpan.org/~miyagawa/App-cpanminus-1.6932/lib/App/cpanminus.pm

注意: cpanmはhttpsを使ってダウンロードされると思います。
httpsを通すようにファイアーウォールを調整しておく必要があります。

perlbrewを入れている場合、install-cpanmコマンドでインストール可能です。

74 :名無しさん名前募集中。。。:2013/07/25(木) 20:21:04.48 ID:WhVb7wVz0
11.3.1 File::Basenameモジュール

使う
use File::Basename;

File::Basenameをロードすると同時に、いくつかの関数もインポートされ、使えるようになります。
作成しているプログラムのサブルーチン名と被るのを避けるには、関数のインポートを止め、
File::Basenameに含まれる関数を呼び出すために、完全修飾名(fully qualified name)で
呼び出すようにします。

use 5.016;
use warnings;
use File::Basename ();

sub dirname { '/mydir' }

my $name = '/foo/bar/baz/qux';
say File::Basename::dirname $name;
say dirname $name;

結果
/foo/bar/baz
/mydir

basename関数だけをインポートしたいときは
use File::Basename qw(basename);


11.3.3 File::Specモジュール

File::Specモジュールでは、クラスメソッドを呼び出す形式で使います。
呼び出し方は、クラス名->メソッド名です。

use 5.016;
use warnings;
use File::Basename qw(basename dirname);
use File::Spec;

my $name = '/foo/bar/baz/qux';
my $dir = dirname $name;
my $base = basename $name;
say File::Spec->catfile($dir, $base);

結果(例:windows環境)
\foo\bar\baz\qux

なお、関数をインポートする形式のFile::Spec::Funcitonsモジュールもあります。

75 :名無しさん名前募集中。。。:2013/07/25(木) 20:47:04.21 ID:WhVb7wVz0
11.3.4 Path::Class

Path::Classは、File::Specより、少しスマートなモジュールです。

use 5.016;
use warnings;
use Path::Class;

my $path = file '/foo/bar/baz/qux';
my $dir = $path->dir;
my $base = $path->basename;
say $dir;
say $base;

結果(例:windows環境)
\foo\bar\baz
qux

Path::Classのfile関数は、Path::Class::Fileのオブジェクトを返します。
そのため、ドキュメントを調べるときは、Path::Class::Fileを参照します。

Path::Class::File
http://search.cpan.org/~kwilliams/Path-Class-0.32/lib/Path/Class/File.pm

76 :名無しさん名前募集中。。。:2013/07/26(金) 20:21:13.99 ID:ijdGhvr80
11.3.5 CGI.pm

CGI.pmモジュールは、少々時代遅れになりましたが、CGI周りの雑事を一手に引き受ける
便利なモジュールです。
オブジェクト指向でも、関数形式でも使えます。
ただ、大量の関数を抱え込んでいるため、関数単位でのインポートが困難です。
そのため、タグ形式による複数の関数をまとめてインポートする方法をサポートしています。

use 5.016;
use warnings;
use CGI qw(:all);

my @list = ('foo', 'bar', 'baz');

print header(-charset => 'utf-8');
print start_html(-title => 'CGI test', -lang => '');

print h1('CGI test.'), "\n";
print ul(li(\@list));

print end_html;

結果
Content-Type: text/html; charset=utf-8

<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>CGI test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<h1>CGI test.</h1>
<ul><li>foo</li> <li>bar</li> <li>baz</li></ul>
</body>
</html>

77 :名無しさん名前募集中。。。:2013/07/26(金) 20:28:12.27 ID:ijdGhvr80
11.3.6 データベースとDBI

DBIは全てをコントロールできる反面、コード量が増えてしまいます。

SQLite3は、サーバではなく、ライブラリの形で提供され、更にメモリ上に
デーブルを作ることができるので、実験向きです。

use 5.016;
use warnings;
use DBI;

my $dbh = DBI->connect(
'DBI:SQLite:dbname=:memory:',
'',
'',
{
RaiseError => 1,
AutoCommit => 0,
sqlite_unicode => 1,
}
) or die $DBI::errstr;
...

$dbh->disconnect;

78 :名無しさん名前募集中。。。:2013/07/26(金) 20:28:53.82 ID:ijdGhvr80
11.3.7 日付と時刻

use 5.016;
use warnings;
use DateTime;
use Time::Piece;

# DateTime
my $dt = DateTime->now(time_zone => 'local');
say $dt->ymd('/'), " ", $dt->hms('.');

# Time::Piece
my $tp = localtime;
say $tp->ymd('/'), " ", $tp->hms('.');

結果(例)
2013/07/26 20.14.41
2013/07/26 20.14.41

Time::Piece等の注意

perlfaq4 - データ操作 昨日の日付を得るには?
http://perldoc.jp/docs/perl/5.14.1/perlfaq4.pod#How32do32I32find32yesterdays32date63
> Perl 5.10 から、Time::Piece と Time::Seconds は標準配布の 一部になったので、
> 以下のようにすることを考えるかもしれません:

> use Time::Piece;
> use Time::Seconds;

> my $yesterday = localtime() - ONE_DAY; # WRONG
> print "Yesterday was $yesterday\n";

> Time::Piece モジュールは、オブジェクトを返す新しい localtime を エクスポートし、
> Time::Seconds は秒数を示す ONE_DAY 定数を エクスポートします。
> これは常に 24 時間前を意味し、常に昨日というわけではありません。
> これは、夏時間の終わりに 1 日が 25 時間ある時に問題があります。

79 :名無しさん名前募集中。。。:2013/07/27(土) 18:37:38.46 ID:NkayLXnQ0
12.1 ファイルテスト演算子

-x
http://perldoc.jp/func/-X
> -X FILEHANDLE
> -X EXPR
> -X DIRHANDLE
> -X
> X は以下にあげる文字で、ファイルテストを行ないます。 この単項演算子は、
> ファイル名かファイルハンドルを唯一の 引数として動作し、「あること」について
> 真であるか否かを 判定した結果を返します。 引数が省略されると、-t では STDIN を
> 調べますが、その他は $_ を調べます。 特に記述されていなければ、真として 1 を
> 返し、偽として '' を返し、ファイルが存在しなければ、未定義値を返します。

> マイナス記号の後に 英字が 1 字続くときにのみ、ファイルテストと解釈されます。

> これらの演算子は上述の「関数のように見えるルール」から免除されます。 つまり、
> 演算子の後の開きかっこは、引き続くコードのどこまでが引数を 構成するかに影響を
> 与えません。 演算子を引き続くコードから分離するには、演算子の前に開きかっこを
> 置いてください (これはもちろん、単項演算子より高い優先順位を持つ 演算子にのみ
> 適用されます):
> -s($file) + 1024 # probably wrong; same as -s($file + 1024)
> (-s $file) + 1024 # correct

> どのファイルテスト (あるいは、stat や lstat) 演算子にも、 下線だけから成る
> 特別なファイルハンドルを与えると、 前回のファイルテスト (や stat) の
> stat 構造体が使われ、 システムコールを省きます。

> Perl 5.9.1 から、純粋にシンタックスシュガーとして、ファイルテスト演算子を
> スタックさせることができるので、-f -w -x $file は -x $file && -w _ && -f _ と
> 等価です。

use 5.016;
use warnings;

$_ = $0;

say -f; # -f $_ file tests
say -fx; # "-fx" string
say -q /a/; # '-a' string

結果(例)
1
-fx
-a

80 :名無しさん名前募集中。。。:2013/07/27(土) 18:38:14.35 ID:NkayLXnQ0
12.2 stat関数とlstat関数

stat
http://perldoc.jp/func/stat
> FILEHANDLE か DIRHANDLE を通じてオープンされているファイルか、 EXPR で
> 指定されるファイルの情報を与える、13 要素のリストを返します。

> File::stat モジュールは、便利な名前によるアクセス機構を提供します。

File::stat - by-name interface to Perl's built-in stat() functions
http://search.cpan.org/~rjbs/perl-5.18.0/lib/File/stat.pm

use 5.016;
use warnings;
use File::stat;

my $sb = stat $0;

printf "File is %s, size is %s, perm %04o, mtime %s\n",
$0, $sb->size, $sb->mode & 07777,
scalar localtime $sb->mtime;

my (
$dev, $ino, $mode, $nlink, $uid, $gid, $rdev,
$size, $atime, $mtime, $ctime, $blksize, $blocks
) = CORE::stat $0;

printf "File is %s, size is %s, perm %04o, mtime %s\n",
$0, $size, $mode & 07777, scalar localtime $mtime;

結果(例)
File is ..., size is 445, perm 0666, mtime Sat Jul 27 12:14:06 2013
File is ..., size is 445, perm 0666, mtime Sat Jul 27 12:14:06 2013

81 :名無しさん名前募集中。。。:2013/07/27(土) 18:38:49.26 ID:NkayLXnQ0
12.3 localtime関数

localtime
http://perldoc.jp/func/localtime
> time 関数が返す時刻を、ローカルなタイムゾーンで測った時刻として、
> 9 要素の配列に変換します。

> Time::gmtime モジュールと Time::localtime モジュールは、それぞれ
> gmtime() 関数と localtime() 関数に、名前でアクセスする機構を提供する
> 便利なモジュールです。

Time::localtime - by-name interface to Perl's built-in localtime() function
http://search.cpan.org/~rjbs/perl-5.18.0/lib/Time/localtime.pm

perl5004delta - what's new for perl5.004
Object-oriented overrides for builtin operators
http://search.cpan.org/~rjbs/perl-5.18.0/pod/perl5004delta.pod#Object-oriented_overrides_for_builtin_operators
> File::stat
> Net::hostent
> Net::netent
> Net::protoent
> Net::servent
> Time::gmtime
> Time::localtime
> User::grent
> User::pwent

82 :名無しさん名前募集中。。。:2013/07/27(土) 18:39:41.99 ID:NkayLXnQ0
12.4 ビット演算子

ビット演算子(bitwise operator)の論理積(&)は、マスク演算に使います。
必要なビットの部分だけに1をセットし、その他を0にすることで、必要なビットだけを
取り出せます。

http://ja.wikipedia.org/wiki/%E3%83%93%E3%83%83%E3%83%88%E3%83%9E%E3%82%B9%E3%82%AF


use 5.016;
use warnings;

my $data = 0b10011101;
my $mask = 0b00001111;
printf("%08b\n", $data & $mask);

結果
00001101


use 5.016;
use warnings;
use File::stat;
use POSIX;

foreach($0, './'){
my $st = stat $_;

say;
say 'user: ',
(($st->mode & S_IRUSR) ? 'read ' : ''),
(($st->mode & S_IWUSR) ? 'write ' : ''),
(($st->mode & S_IXUSR) ? 'execute ' : '');

say 'group: ',
(($st->mode & S_IRGRP) ? 'read ' : ''),
(($st->mode & S_IWGRP) ? 'write ' : ''),
(($st->mode & S_IXGRP) ? 'execute ' : '');

say 'other: ',
(($st->mode & S_IROTH) ? 'read ' : ''),
(($st->mode & S_IWOTH) ? 'write ' : ''),
(($st->mode & S_IXOTH) ? 'execute ' : '');
say '';
}

結果(例:windows環境)
...
user: read write
group: read write
other: read write

./
user: read write execute
group: read write execute
other: read write execute

83 :名無しさん名前募集中。。。:2013/07/29(月) 23:45:59.89 ID:Kmu8j3Wj0
13.1 ディレクトリツリーの中を移動する

chdir
http://perldoc.jp/func/chdir
> chdir EXPR
> chdir FILEHANDLE
> chdir DIRHANDLE
> chdir
> (可能であれば、) カレントディレクトリを EXPR に移します。
> EXPR を指定しないと、$ENV{HOME} が設定されていれば、そのディレクトリに 移ります;
> そうでなく、$ENV{LOGDIR}が設定されていれば、そのディレクトリに 移ります。
> (VMS では $ENV{SYS$LOGIN} もチェックされ、もしセットされていれば 使われます。)
> どちらも設定されていなければ、chdir は何もしません。 成功時には真を返し、
> そうでなければ偽を返します。

84 :名無しさん名前募集中。。。:2013/07/29(月) 23:46:19.63 ID:Kmu8j3Wj0
13.1.1 グロブ

glob
http://perldoc.jp/func/glob
> リストコンテキストでは、 EXPR の値を、標準 Unix シェル /bin/csh が行なうように
> ファイル名の展開を行なった結果のリスト(空かもしれません)を返します。
> スカラコンテキストでは、glob はこのようなファイル名展開を繰り返し、
> リストがなくなったら undef を返します。

> 空でない中かっこが glob で使われている唯一のワイルドカード文字列の 場合、
> ファイル名とはマッチングせず、可能性のある文字列が返されます。

> v5.6.0 から、この演算子は標準の File::Glob 拡張を使って 実装されています。
> 空白をパターンのセパレータとして扱わない bsd_glob を含めた 詳細は
> File::Glob を参照してください。

File::Glob
http://perldoc.perl.org/File/Glob.html


use 5.016;
use warnings;

say join(",", glob '{a,b,c}{1,2,3}');

結果
a1,a2,a3,b1,b2,b3,c1,c2,c3


13.2 グロブのもう1つの書き方

perlop - Perl の演算子と優先順位 I/O 演算子
http://perldoc.jp/docs/perl/5.16.1/perlop.pod#I47O32Operators
> 山括弧の中の文字列がファイルハンドルでもファイルハンドル名、型グロブ、
> 型グロブリファレンスのいずれかが入った単純スカラ変数でもなければ、
> グロブを行なうファイル名のパターンと解釈され、コンテキストによって
> ファイル名のリストか、そのリストの次のファイル名が返されます。
> この区別は単に構文的に行われます。 <$x> は常に間接ハンドルから readline()
> しますが、 <$hash{key}> は常に glob() します。 $x は単純スカラー変数ですが、
> $hash{key} は違う(ハッシュ要素)からです。 <$x > (余分な空白に注意) ですら
> readline($x) ではなく glob("$x ") として扱われます。

85 :名無しさん名前募集中。。。:2013/07/29(月) 23:46:45.24 ID:Kmu8j3Wj0
13.3 ディレクトリハンドル

opendir
http://perldoc.jp/func/opendir
> opendir DIRHANDLE,EXPR
> readdir、telldir、seekdir、rewinddir、closedir で 処理するために、
> EXPR で指定された名前のディレクトリをオープンします。 成功時には真を返します

readdir
http://perldoc.jp/func/readdir
> readdir DIRHANDLE
> opendir でオープンしたディレクトリで、 次のディレクトリエントリを返します。
> リストコンテキストで用いると、 そのディレクトリの残りのエントリを、
> すべて返します。 エントリが残っていない場合には、スカラコンテキストでは
> 未定義値を、 リストコンテキストでは空リストを返します。

> Perl 5.11.2 から裸の readdir を while で使うことができ、
> この場合繰り返し毎に $_ にセットされます。

closedir
http://perldoc.jp/func/closedir
> closedir DIRHANDLE
> opendir でオープンしたディレクトリをクローズし、
> システムコールの返り値を返します。

DirHandle - supply object methods for directory handles
http://perldoc.perl.org/DirHandle.html

use 5.016;
use warnings;
use DirHandle;

my $dir = DirHandle->new('./') or die $!;
while(my $name = $dir->read){
say $name;
}

結果
(略)

86 :名無しさん名前募集中。。。:2013/07/29(月) 23:47:03.47 ID:Kmu8j3Wj0
13.4 再帰的なディレクトリ処理

File::Find - Traverse a directory tree.
http://perldoc.perl.org/File/Find.html

perlopentut - Perl でいろんなものを開くためのチュートリアル ファイルでないファイルを開く
http://perldoc.jp/docs/perl/5.16.1/perlopentut.pod#Opening32Non-File32Files
> ディレクトリを再帰的に処理したい場合は、File::Find モジュールを使った方が
> いいでしょう。 例えば、これは全てのファイルを再帰的に表示して、
> もしファイルが ディレクトリの場合は末尾にスラッシュを追加します。

> @ARGV = qw(.) unless @ARGV;
> use File::Find;
> find sub { print $File::Find::name, -d && '/', "\n" }, @ARGV;

13.6 ファイルを削除する

unlink
http://perldoc.jp/func/unlink
> unlink LIST
> unlink
> LIST に含まれるファイルを削除します。 成功時は削除に成功したファイルの数を
> 返します。 失敗時は偽を返して $! (error) をセットします:
> LIST が省略されると、unlink は $_ を使います。

13.7 ファイルの名前を変更する

rename
http://perldoc.jp/func/rename
> rename OLDNAME,NEWNAME
> ファイルの名前を変更します; NEWNAME というファイルが既に存在した場合、
> 上書きされるかもしれません。 成功時には真を、さもなければ偽を返します。

File::Copy - Copy files or filehandles
http://perldoc.perl.org/File/Copy.html

13.8 リンクとファイル

link
http://perldoc.jp/func/link
> link OLDFILE,NEWFILE
> OLDFILE にリンクされた、新しいファイル NEWFILE を作ります。
> 成功時には真を、さもなければ偽を返します。

symlink
http://perldoc.jp/func/symlink
> symlink OLDFILE,NEWFILE
> NEWFILE として、OLDFILE へのシンボリックリンクを生成します。
> 成功時には 1 を返し、失敗時には 0 を返します。 シンボリックリンクを
> サポートしていないシステムでは、 例外が発生します。

readlink
http://perldoc.jp/func/readlink
> readlink EXPR
> readlink
> シンボリックリンクが実装されていれば、 シンボリックリンクの値を返します。
> 実装されていないときには、例外が発生します。 何らかのシステムエラーが
> 検出されると、未定義値を返し、 $! (errno) を設定します。
> EXPR が省略されると、$_ を使います。

87 :名無しさん名前募集中。。。:2013/07/29(月) 23:47:32.38 ID:Kmu8j3Wj0
13.9 ディレクトリの作成と削除

mkdir
http://perldoc.jp/func/mkdir
> mkdir FILENAME,MASK
> mkdir FILENAME
> mkdir
> FILENAME で指定したディレクトリを、MASK で指定した許可モード(を umask
> で修正したもの) で作成します。 成功時には真を返します; さもなければ
> 偽を返して $! (errno) を設定します。 MASK を省略すると、0777 とみなし、
> FILENAME を省略すると、$_ を使います。

rmdir
http://perldoc.jp/func/rmdir
> rmdir FILENAME
> rmdir
> FILENAME で指定したディレクトリが空であれば、 そのディレクトリを削除します。
> 成功時には真を返します; さもなければ偽を返して $! (errno) を設定します。
> FILENAME を省略した場合には、$_ を使用します。

File::Path - Create or remove directory trees
http://perldoc.perl.org/File/Path.html

13.10 パーミッションを変更する

chmod
http://perldoc.jp/func/chmod
> chmod LIST
> LIST に含まれるファイルの、パーミッションを変更します。 LIST の最初の要素は、
> 数値表現のモードでなければなりません; 恐らく 8 進表記の数であるべきでしょう:
> しかし、8 進表記の 文字列ではいけません: 0644 は OK ですが、 '0644' は だめ、
> ということです。 変更に成功したファイルの数を返します。 文字列を使いたい場合は、
> oct を参照してください。

なぜ私の 8 進データは正しく解釈されないのでしょうか?
http://perldoc.jp/docs/perl/5.14.1/perlfaq4.pod#Why32isnt32my32octal32data32interpreted32correctly63
> コマンドラインの chmod は、最初の引数として 8 進数を 求めているので、
> 最初の引数が 8 進数だと分かっています:

> %prompt> chmod 644 file

> もし同じリテラルの数字 (644) を Perl で使いたいなら、 先頭に 0 を付けるか oct を
> 使うことで Perl にこれを 8 進数で 扱うように教える必要があります:

> chmod( 0644, $file); # right, has leading zero
> chmod( oct(644), $file ); # also correct

> この問題は、Perl が文字列として考えているところ、例えば @ARGV の
> コマンドライン引数から数字を持ってくる場合に起こります:

88 :名無しさん名前募集中。。。:2013/07/29(月) 23:47:52.97 ID:Kmu8j3Wj0
13.11 ファイルのオーナーを変更する

chown
http://perldoc.jp/func/chown
> chown LIST
> LIST に含まれるファイルの所有者 (とグループ) を変更します。 LIST の最初の
> 二つの要素には、数値表現 の uid と gid を この順序で与えなければなりません。
> どちらかの値を -1 にすると、ほとんどのシステムではその値は 変更しないと
> 解釈します。 変更に成功したファイルの数を返します。

13.12 タイムスタンプを変更する

utime
http://perldoc.jp/func/utime
> utime LIST
> ファイルのアクセス時刻と修正(modification) 時刻を変更します。 LIST の
> 最初の二つの要素に、数値で表わしたアクセス時刻と修正時刻を 順に指定します。
> 変更に成功したファイルの数を返します。 各ファイルの inode 変更(change)時刻には、
> その時点の時刻が設定されます。

89 :名無しさん名前募集中。。。:2013/07/30(火) 22:24:20.13 ID:/fZuR1jC0
14.1 indexを使って部分文字列を探す

index
http://perldoc.jp/func/index
> index STR,SUBSTR,POSITION
> index STR,SUBSTR
> index 関数は ある文字列をもうひとつの文字列から検索しますが、 完全正規表現
> パターンマッチのワイルドカード的な振る舞いはしません。 STR の中の POSITION の
> 位置以降で、最初に SUBSTR が見つかった位置を返します。 POSITION が省略された
> 場合には、STR の最初から探し始めます。 POSITION が文字列の先頭より前、
> あるいは末尾より後ろを指定した場合は、 それぞれ先頭と末尾を指定されたものとして
> 扱われます。 POSITION と返り値のベースは、0 です。 SURSTR が
> 見つからなかった場合には、index は -1 が返されます。

rindex
http://perldoc.jp/func/rindex
> rindex STR,SUBSTR,POSITION
> rindex STR,SUBSTR
> STR 中で 最後に 見つかった SUBSTR の位置を返すことを除いて、 index() と
> 同じように動作します。 POSITION を指定すると、その位置から始まるか、
> その位置より前の、 最後の位置を返します。

90 :名無しさん名前募集中。。。:2013/07/30(火) 22:24:57.89 ID:/fZuR1jC0
14.2 substrを使って部分文字列をいじる

substrをLvalue(代入先)に使うのは、お勧めしません。

substr
http://perldoc.jp/func/substr
> substr EXPR,OFFSET,LENGTH,REPLACEMENT
> substr EXPR,OFFSET,LENGTH
> substr EXPR,OFFSET
> EXPR から、部分文字列を取り出して返します。 最初の文字がオフセット 0 となります。
> OFFSET に負の値を設定すると、EXPR の終わりからのオフセットとなります。
> LENGTH を省略すると、EXPR の最後まですべてが返されます。 LENGTH が負の値だと、
> 文字列の最後から指定された数だけ文字を取り除きます。

> 負数のオフセットの場合、ターゲット文字列が修正されたときに文字列の末尾からの
> 位置を覚えます:
> バージョン 5.10 より前の Perl では、複数回左辺値を使った場合の結果は
> 未定義でした。 5.16 より前では、負のオフセットの結果は未定義です。

perl5100delta - perl 5.10.0 の新機能 substr() の lvalue は固定長でなくなりました
http://perldoc.jp/docs/perl/5.12.1/perl5100delta.pod#substr40lvalue32
> 3引数形式の substr() から返される lvalue 値は オリジナルの文字列での
> "固定長のウィンドウ"を持っていました. いくつかのケースにおいてこれは離れた
> 場所でのびっくりする動作や 他の未定義な振る舞いとなっていました.
> このウィンドウの長さはそれに代入された文字列の長さに 調整されるようになりました.
> (編注:$x="1234";$y=(substr($x,1,2)="ABCD"); とした時, これまでは $x="1ABCD4",
> $y="AB" となっていたけれど, 5.10 以降は $x="1ABCD4", $y="ABCD" になる.)

91 :名無しさん名前募集中。。。:2013/07/30(火) 22:25:14.55 ID:/fZuR1jC0
perl5160delta - perl v5.16.0 での変更点 substr lvalue revamp
http://perldoc.jp/docs/perl/5.16.0/perl5160delta.pod#substr32lvalue32revamp
> 左辺値や潜在的な左辺値コンテキストで 2 引数または 3 引数の substr が
> 呼び出されると、代入するときに元の文字列(1 番目の引数)を修正する
> 特殊な左辺値スカラを返します。

> my $string = "string";
> my $lvalue = \substr $string, -4, 2;
> print $$lvalue, "\n"; # prints "ri"
> $string = "bailing twine";
> print $$lvalue, "\n"; # prints "wi"; used to print "il"

use 5.016;
use warnings;

my $string = 'London bridge is broken down';
my $part = \(substr $string, -4, 4);
say ${$part};

$string = 'My fair lady';
say ${$part};

結果
down
lady


use strict;
use warnings;

my $string = 'London bridge is broken down';
my $part = substr($string, 17, 6) = 'falling';
print $part, "\n";
print $string, "\n";

結果(5.16)
falling
London bridge is falling down

結果(5.8)
fallin
London bridge is falling down

92 :名無しさん名前募集中。。。:2013/07/30(火) 22:25:35.22 ID:/fZuR1jC0
14.3 sprintfを使ってデータをフォーマットする

適当な丸め

perlfaq4 - データ操作
なぜ 19.95 のような数字ではなく、19.9499999999999 のような長い数字が出てきたんでしょうか?
http://perldoc.jp/docs/perl/5.14.1/perlfaq4.pod#Why32am32I32getting32long32decimals32eg4419.949999999999941instead32of32the32numbers32I32should32be32getting32eg4419.9541
> 10 進数の桁数を制限するには、printf や sprintf の関数が使えます。
> 更なる詳細については "Floating Point Arithmetic" in perlop を参照してください。
> printf "%.2f", 10/3;
> my $number = sprintf "%.2f", 10/3;

perlop - Perl の演算子と優先順位 浮動小数点数演算
http://perldoc.jp/docs/perl/5.16.1/perlop.pod#Floating32Point32Arithmetic

use 5.016;
use warnings;

say 1.2 - 1.1;
printf "%.2f", 1.2 - 1.1;

結果
0.0999999999999999
0.10

93 :名無しさん名前募集中。。。:2013/07/30(火) 22:25:52.14 ID:/fZuR1jC0
数値にカンマを入れる

出力する数字にカンマを付加するには?
http://perldoc.jp/docs/perl/5.14.1/perlfaq5.pod#How32can32I32output32my32numbers32with32commas32added63

Number::Format - Perl extension for formatting numbers
http://search.cpan.org/~wrw/Number-Format-1.73/Format.pm

use 5.016;
use warnings;
use Number::Format qw(:subs);

say format_number(12345678.90);

結果
12,345,678.9


14.3.2 10進以外の数を解釈する

hex
http://perldoc.jp/func/hex
> hex EXPR
> hex
> EXPR を 16 進数の文字列と解釈して、対応する値を返します。
> (0, 0x, 0b で始まる文字列の変換には、oct を 参照してください。)
> EXPR が省略されると、$_ を使います。

oct
http://perldoc.jp/func/oct
> oct EXPR
> oct
> EXPR を 8 進数文字列と解釈して、対応する値を返します。
> (EXPR が 0x で始まるときには、16 進数文字列と解釈します。 EXPR が
> 0bで始まるときは、2 進数文字列と解釈します。 どの場合でも、先頭の空白は
> 無視されます。)

94 :名無しさん名前募集中。。。:2013/07/30(火) 22:26:17.94 ID:/fZuR1jC0
14.4 高度なソート

sort
http://perldoc.jp/func/sort
> sort SUBNAME LIST
> sort BLOCK LIST
> sort LIST
> リストコンテキストでは、LIST をソートし、ソートされたリスト値を返します。
> スカラコンテキストでは、sort() の振る舞いは未定義です。

> SUBNAME や BLOCK を省略すると、標準の文字列比較の順番でソートが 行なわれます。
> SUBNAME を指定すると、それは、リストの要素をどのような順番に並べるかに
> 応じて、負、ゼロ、正の整数を返すサブルーチンの名前であると解釈されます。

> use locale が有効(そして use locale 'not_characters' が有効でない)の
> 場合、sort LIST は LIST を現在の比較ロケールに従ってソートします。

> <=> はどちらかのオペランドが NaN (not-a-number) のときに undef を返すので、
> $a <=> $b といった比較関数でソートする場合はリストに NaN が 含まれないように
> 注意してください。 以下の例は 入力リストから NaN を取り除くために
> NaN != NaN という性質を 利用しています。

> @result = sort { $a <=> $b } grep { $_ == $_ } @input;

perlop - Perl の演算子と優先順位 等価演算子
http://perldoc.jp/docs/perl/5.16.1/perlop.pod#Equality32Operators
> 二項演算子の "<=>" は左引数が数値的に右引数より小さいか、等しいか、
> 大きいかに従って、-1, 0, 1 を返します。
> 数値として NaN (非数) に対応しているプラットフォームでは、
> NaN に対して "<=>" を使うと undef を返します。

> 二項演算子の "cmp" は左引数が文字列的に右引数より小さいか、
> 等しいか、大きいかに従って、-1, 0, 1 を返します。

95 :名無しさん名前募集中。。。:2013/07/30(火) 22:26:37.35 ID:/fZuR1jC0
Unicodeにおける比較

Unicode::Normalize - Unicode Normalization Forms
http://search.cpan.org/~sadahiro/Unicode-Normalize-1.16/Normalize.pm

Unicode正規化
http://ja.wikipedia.org/wiki/Unicode%E6%AD%A3%E8%A6%8F%E5%8C%96
Unicodeの互換文字
http://ja.wikipedia.org/wiki/Unicode%E3%81%AE%E4%BA%92%E6%8F%9B%E6%96%87%E5%AD%97

use 5.016;
use warnings;
use Unicode::Normalize;
use charnames qw(:full);

foreach(
['roman six' => "\N{ROMAN NUMERAL SIX}"],
['roman five one' => "\N{ROMAN NUMERAL FIVE}\N{ROMAN NUMERAL ONE}"],
['five one' => 'VI'],
['NFKD roman six' => NFKD("\N{ROMAN NUMERAL SIX}")],
['NFKD romna five one' => NFKD("\N{ROMAN NUMERAL FIVE}\N{ROMAN NUMERAL ONE}")],
){
printf("%s: %0*v4X\n", $_->[0], ',', $_->[1]);
}

結果
roman six: 2165
roman five one: 2164,2160
five one: 0056,0049
NFKD roman six: 0056,0049
NFKD romna five one: 0056,0049


use 5.016;
use warnings;
use Unicode::Normalize;
use charnames qw(:full);

my @array = (
"\N{ROMAN NUMERAL FOUR}",
"\N{ROMAN NUMERAL ONE}\N{ROMAN NUMERAL ONE}",
"III",
);

foreach(sort{ NFKD($a) cmp NFKD($b) } @array){
printf("%0*v4X\n", ',', $_);
}

結果
2160,2160
0049,0049,0049
2163

96 :名無しさん名前募集中。。。:2013/07/30(火) 22:54:20.69 ID:/fZuR1jC0
14.4.1 ハッシュ値によってソートする

perlfaq4 - データ操作 ハッシュを(キーではなく値で)ソートするには?
http://perldoc.jp/docs/perl/5.14.1/perlfaq4.pod#How32do32I32sort32a32hash32optionally32by32value32instead32of32key41
> ハッシュの値でソートしたいなら、それを探すためにハッシュキーを 使います。
> やはりキーのリストを使いますが、今度はその値でソートします。
> my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash;

14.4.2 複数のキーでソートする

perlfaq4 - データ操作 (なにか)で配列をソートするには?
http://perldoc.jp/docs/perl/5.14.1/perlfaq4.pod#How32do32I32sort32an32array32by32anything41
> 幾つかのフィールドを使ってソートする必要があるのなら、
> 以下のやり方が便利でしょう。
> @sorted = sort {
> field1($a) <=> field1($b) ||
> field2($a) cmp field2($b) ||
> field3($a) cmp field3($b)
> } @data;

> ソートするものの一部を取り出す必要があるような複雑な関数を使うのなら、
> ソート関数の内側でそれを使ってはいけません。 最初にその関数で使う部分を
> 取り出します。 なぜなら、sort BLOCK は同じ要素に対して何度も何度も
> 呼び出される 可能性があるからです。

> シュワルツ変換と呼ばれるトリックを使って以下のように 書くこともできます:

> @sorted = map { $_->[0] }
> sort { $a->[1] cmp $b->[1] }
> map { [ $_, uc( (/\d+\s*(\S+)/)[0]) ] } @data;

97 :名無しさん名前募集中。。。:2013/07/30(火) 22:54:44.61 ID:/fZuR1jC0
use 5.016;
use warnings;
use Unicode::Normalize;
use charnames qw(:full);
use Roman;

my @array = (
"\N{ROMAN NUMERAL FOUR}",
"\N{ROMAN NUMERAL ONE}\N{ROMAN NUMERAL ONE}",
"C",
"III",
);

my @sorted =
map{ $_->[0] }
sort{ $a->[1] <=> $b->[1] }
map{ [$_, arabic NFKD($_)] }
@array;

foreach(@sorted){
printf("%0*v4X\n", ',', $_);
}

結果
2160,2160
0049,0049,0049
2163
0043

98 :名無しさん名前募集中。。。:2013/08/01(木) 19:08:01.19 ID:VNqrjkmS0
16.1 system関数

system
http://perldoc.jp/func/system
> system LIST
> system PROGRAM LIST
> exec LIST とほとんど同じですが、まず fork を行ない、 親プロセスでは
> チャイルドプロセスが終了するのを wait します。 exec の項で述べたように、
> 引数の処理は、引数の数によって異なることに 注意してください。 LIST に
> 複数の引数がある場合、または LIST が複数の要素からなる配列の場合、 リストの
> 最初の要素で与えられるプログラムを、リストの残りの要素を引数として 起動します。
> スカラの引数が一つだけの場合、引数はシェルのメタ文字をチェックされ、もし
> あればパースのために引数全体がシステムコマンドシェル (これは
> Unix プラットフォームでは /bin/sh -c ですが、他のプラットフォームでは
> 異なります)に渡されます。 シェルのメタ文字がなかった場合、引数は単語に
> 分解されて直接 execvp に 渡されます; この方がより効率的です。
> 返り値は、wait が返すプログラムの exit 状態です。 実際の exit 値を得るには
> 右に 8 ビットシフトしてください(後述)。 exec も参照してください。

16.1.1 シェルの起動を避ける

スカラ値でシステムシェルにコマンドを渡す場合、コマンドインジェクション脆弱性を
常に考慮してください。

16.2 環境変数

Env - perl module that imports environment variables as scalars or arrays
http://perldoc.perl.org/Env.html

use 5.016;
use warnings;
use Env qw(TZ);

say scalar localtime;

if (@ARGV < 1){
local $TZ = 'UCT10'; # Hawaii
system('perl', $0, 1);
}

結果(例)
Thu Aug 1 19:07:34 2013
Thu Aug 1 00:07:34 2013


16.3 exec関数

exec
http://perldoc.jp/func/exec
> exec LIST
> exec PROGRAM LIST
> exec 関数は、システムのコマンドを実行し、戻ってはきません;
> コマンドが存在せず、しかも システムのコマンドシェル経由でなく
> 直接コマンドを実行しようとした場合にのみこの関数は失敗して偽を返します。

99 :名無しさん名前募集中。。。:2013/08/01(木) 19:08:40.71 ID:VNqrjkmS0
16.4 逆クォートを使って出力を取り込む

perlop - Perl の演算子と優先順位 クォート風演算子
http://perldoc.jp/docs/perl/5.16.1/perlop.pod#Quote-Like32Operators
> qx/STRING/
> `STRING`
> 展開され、/bin/sh またはそれと等価なものでシステムのコマンドとして
> 実行される(であろう)文字列です。 シェルのワイルドカード、パイプ、
> リダイレクトが有効です。 そのコマンドの、標準出力を集めたものが返されます;
> 標準エラーは影響を 与えません。 スカラコンテキストでは、(複数行を含むかも
> しれない) 1 つの文字列が戻ってきます; コマンドが失敗したときは未定義値を
> 返します。 リストコンテキストでは、($/ もしくは $INPUT_RECORD_SEPARATOR を
> どのように設定していても) 行のリストを返します; コマンドが失敗したときは
> 空リストを返します。

16.5 IPC::System::Simpleによる外部プロセスの起動

IPC::System::Simple - Run commands simply, with detailed diagnostics
http://search.cpan.org/~pjf/IPC-System-Simple-1.21/lib/IPC/System/Simple.pm

use 5.016;
use warnings;
use IPC::System::Simple qw(capturex);

my $line = (
$^O =~ /Win32/i ?
q{"print qq{Hello, world!\n}"} :
q{print qq{Hello, world!\n}}
);

print capturex('perl', '-e', $line);

結果
Hello, world!


※Windows環境下ではダブルクォートで挟む必要があるようです。

100 :名無しさん名前募集中。。。:2013/08/01(木) 19:08:55.83 ID:VNqrjkmS0
16.6 プロセスをファイルハンドルとして使う

perlipc - Perl のプロセス間通信 (シグナル, fifo, パイプ, 安全な副プロセス, ソケット, セマフォ)
IPC のために open() を使う
http://perldoc.jp/docs/perl/5.16.1/perlipc.pod#Using32open40for32IPC
> Perlの open() 文は、その第二引数でパイプシンボルを前置するか末尾に
> 付加することによって、一方向のプロセス間通信のために使うことができます。
> 以下の例は、書き込みを行いたい子プロセスを起動させるやり方です:

> open(SPOOLER, "| cat -v | lpr -h 2>/dev/null")
> || die "can't fork: $!";
> local $SIG{PIPE} = sub { die "spooler pipe broke" };
> print SPOOLER "stuff\n";
> close SPOOLER || die "bad spool: $! $?";

>そして以下の例はそこから読み込みを行いたい子プロセスを起動する方法です:

> open(STATUS, "netstat -an 2>&1 |")
> || die "can't fork: $!";
> while (<STATUS>) {
> next if /^(tcp|udp)/;
> print;
> }
> close STATUS || die "bad netstat: $! $?";

> open() と close() の戻り値をチェックするときは注意してください。
> パイプに対して 書き込み をしたのなら、SIGPIPE をトラップすべきです。
> そうしなければ、存在しないコマンドに対するパイプを起動したときに
> 起こることについて考え込むことになるでしょう: open() はほとんどの
> 場合成功すると見込まれるでしょうが(これは fork() の成功だけを
> 反映します)、あなたの出力はその後で壮観に(spectacularly)失敗するでしょう。
> コマンドは、実際には exec() が失敗している別のプロセスで
> 実行されているので、Perl はコマンドがうまく動いているかどうかを
> 知ることはできません。

101 :名無しさん名前募集中。。。:2013/08/01(木) 19:09:14.43 ID:VNqrjkmS0
16.7 forkを使って低レベル処理を行なう

fork
http://perldoc.jp/func/fork
> fork
> 同じプログラムの同じ地点から開始する新しいプロセスを作成するために
> システムコール fork(2) を行ないます。 親プロセスには、チャイルドプロセスの
> pid を、 チャイルドプロセスに 0 を返しますが、 fork に失敗したときには、
> undefを返します。 ファイル記述子(および記述子に関連するロック)は共有され、
> その他の全てはコピーされます。

perlfork - Perl の fork エミュレーション
http://perldoc.jp/docs/perl/5.16.1/perlfork.pod
> Windows といった fork() システムコールを持っていないいくつかの
> プラットフォームでは、インタプリタレベルで fork() のエミュレーションを
> 構築します。

use 5.016;
use warnings;

my $pid = fork;
defined $pid or die "cannot fork: $!";
if (!$pid){
exec 'perl', '-e', 'print qq{Hello, World!\n}';
die "cannot exec: $!";
}

waitpid($pid, 0);

結果
Hello, World!

102 :名無しさん名前募集中。。。:2013/08/01(木) 19:09:33.10 ID:VNqrjkmS0
16.8 シグナルを送受信する

perlipc - Perl のプロセス間通信 (シグナル, fifo, パイプ, 安全な副プロセス, ソケット, セマフォ)
シグナル
http://perldoc.jp/docs/perl/5.16.1/perlipc.pod#Signals

kill
http://perldoc.jp/func/kill
> kill SIGNAL, LIST
> kill SIGNAL
> プロセスのリストにシグナルを送ります。 シグナル送信に成功したプロセスの数を
> 返します (実際に kill に成功したプロセスと同じとは限りません)。

> SIGNAL がゼロの場合、プロセスにシグナルは送られませんが、 kill は、
> シグナルを送ることが 可能 かどうかを調べます (これは、簡単に言うと、
> プロセスが同じユーザーに所有されているか、 自分がスーパーユーザーであることを
> 意味します)。 これは子プロセスが(ゾンビとしてだけでも)まだ生きていて、
> UID が 変わっていないことを調べる時に有用です。

> PROCESS 番号が 0 あるいは負数の場合の kill の振る舞いは オペレーティング
> システムに依存します。

use 5.016;
use warnings;

sub report {
say $_[0], ': process ', (kill(0 => $_[0]) ? 'live?' : 'dead');
}

my $pid = fork;
defined $pid or die "cannot fork: $!";
if (not $pid){
say "$$: child process";
say "$$: exit";
exit;
}

say "$$: parent process";
sleep 1;

print grep{ /$pid/ } `ps ax`;
report($pid);

say "$$: child($pid) wait...";
waitpid($pid, 0);
report($pid);

結果(例:Debian)
28823: parent process
28824: child process
28824: exit
28824 pts/3 Z+ 0:00 [perl] <defunct>
28824: process live?
28823: child(28824) wait...
28824: process dead

プロセスはexitしてから、waitで回収されるまでゾンビプロセスになります。
適切にwaitしてください。
絶対にゾンビにしたくない場合は、二重fork(double-fork)がお勧めです。

perlfaq8 - システムとの相互作用 バックグラウンドでプロセスを起動するには?
http://perldoc.jp/docs/perl/5.14.1/perlfaq8.pod#How32do32I32start32a32process32in32the32background63

103 :名無しさん名前募集中。。。:2013/08/02(金) 21:34:18.29 ID:iYBp7RAY0
17.1 スライス

perldata - Perl のデータ型 スライス
http://perldoc.jp/docs/perl/5.16.1/perldata.pod#Slices
> スライスは、添え字のリストを使ってリスト、配列、ハッシュの複数の要素に
> 同時にアクセスします。 これはそれぞれの要素を個々のスカラ値のリストとして
> 扱うより便利です。

> ($him, $her) = @folks[0,-1]; # array slice
> @them = @folks[0 .. 3]; # array slice
> ($who, $home) = @ENV{"USER", "HOME"}; # hash slice
> ($uid, $dir) = (getpwnam("daemon"))[2,7]; # list slice

> 変数のリストに代入できるので、配列やハッシュのスライスにも代入できます。

> @days[3..5] = qw/Wed Thu Fri/;
> @colors{'red','blue','green'}
> = (0xff0000, 0x0000ff, 0x00ff00);
> @folks[0, -1] = @folks[-1, 0];

104 :名無しさん名前募集中。。。:2013/08/02(金) 21:34:42.80 ID:iYBp7RAY0
17.2 エラーをトラップする

17.1 evalを利用する

eval
http://perldoc.jp/func/eval
> 実行するコードが変わらないのであれば、毎回多量の再コンパイルすることなしに、
> 実行時エラーのトラップを行なうために、 eval-BLOCK 形式を使うことができます。
> エラーがあれば、やはり $@ に返されます。 例:

> # make divide-by-zero nonfatal
> eval { $answer = $a / $b; }; warn $@ if $@;

17.2.2 高度なエラー処理

エラー処理の1つに、例外(exception)という概念があり、
Perlではモジュールでカバーします。

Try::Tiny - minimal try/catch with proper preservation of $@
http://search.cpan.org/~doy/Try-Tiny-0.16/lib/Try/Tiny.pm

autodie - レキシカルスコープ内の関数を、成功しなければ die するものに置き換える
http://perldoc.jp/docs/modules/autodie-2.06_01/autodie.pod

use 5.016;
use warnings;
use Try::Tiny;

try {
use autodie qw(:io);
open my $fh, '<', 'foobar';
while(<$fh>){
print uc;
}
$fh->close;
}
catch {
if ($_->isa('autodie::exception')){
print "I/O error:\n", $_;
}
else {
die $_;
}
};

結果(例)
I/O error:
Can't open 'foobar' for reading: 'No such file or directory' at ... line 7

Try::Tinyとautodieを正直に使うと、少々冗長かも知れません。
例外を扱うモジュールは他にもあるので、色々試してみると良いと思います。

105 :名無しさん名前募集中。。。:2013/08/02(金) 21:35:03.86 ID:iYBp7RAY0
17.3 grepを使ってリストから要素を選び出す

grep
http://perldoc.jp/func/grep
> grep BLOCK LIST
> grep EXPR,LIST
> これは grep(1) とその親類と同じようなものですが、同じではありません。
> 特に、正規表現の使用に制限されません。
> LIST の個々の要素に対して、BLOCK か EXPR を評価し ($_ は、ローカルに
> 個々の要素が設定されます) 、 その要素のうち、評価した式が真となった
> ものからなるリスト値が返されます。 スカラコンテキストでは、
> 式が真となった回数を返します。

use 5.016;
use warnings;

my @array = grep{ chr =~ /\d/ } (1..63);
say "@array";

結果
48 49 50 51 52 53 54 55 56 57


17.4 mapを使ってリストの要素を変換する

map
http://perldoc.jp/func/map
> map BLOCK LIST
> map EXPR,LIST
> LIST の個々の要素に対して、BLOCK か EXPR を評価し ($_ は、ローカルに
> 個々の要素が設定されます) 、 それぞれの評価結果からなるリスト値が
> 返されます。 スカラコンテキストでは、生成された要素の数を返します。

use 5.016;
use warnings;

my @array = map{ sprintf "%04b", $_ } (1..15);
print "@array";

結果
0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111

106 :名無しさん名前募集中。。。:2013/08/02(金) 21:35:21.21 ID:iYBp7RAY0
17.5 便利なリストユーティリティ

List::Util - A selection of general-utility list subroutines
http://perldoc.perl.org/List/Util.html

List::MoreUtils - Provide the stuff missing in List::Util
http://search.cpan.org/~rurban/List-MoreUtils/lib/List/MoreUtils.pm

use 5.016;
use warnings;
use List::Util qw(shuffle);

foreach(1..3){
say "@{[shuffle 1..5]}";
}

結果(例)
2 4 5 3 1
5 1 4 2 3
4 1 3 2 5

107 :名無しさん名前募集中。。。:2013/08/02(金) 21:35:39.63 ID:iYBp7RAY0
おわり。

108 :名無しさん名前募集中。。。:2013/08/06(火) 11:07:49.60 ID:YfFbl2q.0
>>107
おつかれ。

109 :名無しさん名前募集中。。。:2013/08/11(日) 17:34:41.32 ID:dHHUvC5x0
>>108
どもです。

暇なので書評。

Perl徹底攻略
http://gihyo.jp/book/2013/978-4-7741-5864-8

いまどきのPerlの紹介から始まり、Webプログラミング、インフラのHowTo系の
8ページ前後の記事が何本か入った本です。

ぬっちゃけ、「続きはWebで」前提の本だと思いますが、
webでは、知らないことを検索することはできないので、
取っ掛かりとなる、このような本が書店に並ぶのは、いいですね。

いずれも質の良い情報なので、入門を終えて、Perlで何ができるかを
知りたい方にもお勧めです。

128KB
新着レスの表示

名前: E-mail(省略可)
READ.CGI - 0ch+ BBS 0.7.4 20131106
ぜろちゃんねるプラス