kdoc - Perl

  • 作成日:2006-09-05 15:01:55
  • 修正日:2010-07-05 11:07:13

基本

↑ページトップへ

たまに整理するけど、基本的にでたらめなメモ。

クォート

#'abc'
q{abc}
#"abc_$d"
qq{abc_$d}
#`uptime`
qx{uptime}
#(1, 2, 3)
qw{1 2 3}
#正規表現
qr/PATTERN/option
#/PATTERN/
m{PATTERN}
#s/PATTERN//
s{PATTERN}{}
#tr///
tr{}{}

数値

#四捨五入
my $res = int($num + 0.5);
#サイコロ
my $res = int(rand 6) + 1;

2進数/8進数/16進数

#2進数(先頭に0b)
my $num_bin = 0b1111;
#8進数(先頭に0)
my $num_oct = 0777;
#16進数(先頭に0x)
my $num_hex = 0xFFFF;
#16進数→10進数
my $aaa = hex('fa7a');
#10進数→16進数
my $bbb = sprintf("%lx", '367156');
#文字→16進数
my $hex = unpack("H*", 'あ');
#asciiから
my $text = chr(29);
#asciiへ
my $ascii = ord('あ');

printf/sprintf

my $num = 37;
my $formated = sprintf "%05d", $num; # --> 00037
#符号付き整数として解釈し、ゼロで埋めて8桁に
%08d
#浮動小数点として解釈し、小数点以下2位まで(ほぼ四捨五入=0.725が0.72499999…等)
%.2f
#文字列として解釈し、右詰めにしてスペースで埋める
%5s
#文字列として解釈し、左詰めにしてスペースで埋める
%-5s
#文字列として解釈し、右詰めにしてゼロで埋める
%05s

配列

#要素数
my $count = @a;
#最後の要素
my $last = $ary[-1];
#末尾に追加
push @ary, $a;
#先頭を削除
shift @ary;
#末尾を削除
pop @ary;
#先頭に追加
unshift @ary;
my $first = shift @ary;
my $last = pop @ary;
#スライス
my @res = @ary[3, 7];
my @res = @ary[0 .. 4];
#スライス(代入)
my @ary[2, 3] = ('b', 'c');
#splice(5要素目から3つ取得)
my @res = splice @ary, 4, 3;
#splice(5要素目に@addを追加)
my @res = splice @ary, 4, 0, @add;

ハッシュ

#KeyとValueを入れ替え
%hash = reverse %hash;
#Keyの数
my @ary = %hash;
my $countPre = @ary;
my $count = $countPre / 2;
-or-
my $countPre = @ary = %hash;
-or-
my $count = scalar keys %hash;
#結合
my %ccc = (%aaa, %bbb);
#キーと値の削除
delete $hash{$key};
#キーの存在チェック
if(exists $hash{$key}){
}
#値の定義チェック(0は「定義」、undefは「未定義」)
if(defined $hash{$key}){
}
#ループ
foreach my $key(keys %hash){
}
foreach my $value(value %hash){
}
while( my($key, $value) = each %hash){
}
#キー順にループ
foreach my $key( sort {$hash{$b} <=> $hash{$a} } keys %hash ){
}

やり方

↑ページトップへ

パスワード作成

sub makePassword{
  my $num = shift;
  my $pwd;
  $pwd .= ('a' .. 'z', 0 .. 9)[int(rand(36))] while $num -- > 0;
  return $pwd;
}

ヒアドキュメント中のプログラム

$out = <<HTML;
<html>
<head>
<title>${………}</title>
</head>
<body>
HTML

数字列とそれ以外の文字を"@"で分ける

my $text = 'あいうabcかきくdef';
$text =〜 s/(\D*)(\d+)(\D*)/$1@$2@$3/g;

文字変換

#すべて小文字へ
$string =~ tr/A-Z/a-z/;
#a-z以外の文字を削除
$string =~ tr/a-z//cd;

合計

$sum += $_ for @numbers;

substr

#先頭から2byte
my $res = substr($a, 0, 2);
#末尾5文字
my $res = substr($a, -5);
#末尾5文字を削除
substr($a, -5) = '';
#末尾2byteを削除した残り
my $res = substr($a, 0, -2);
#先頭3文字を削除した残り
my $res = substr($a, 3);
#19730307の場合
my $YY = substr $date, 0, 4;
my $MM = substr $date, 4, 2;
my $DD = substr $date, 6, 2;

grep

my @results = grep $expression, @inputList;
my $count = grep $expression, @inputList;
my @results = grep $_ > 10, @in;
my @results = grep /^\d$/, @in;
my @results = grep test($_), @in;
sub test{
 …
 return 1;
}
my @results = grep {…} @in;
#@inの前のカンマなし。{…}ではreturnは書かない。
#空要素削除
my @results = grep length $_, @in;
#空白要素削除
my @results = grep {
  if(/^¥s+$/){
    $_ = undef;
  }
  $_;
} @in;

map

my @results = map function($_), @in;
my @results = map {...} @in;

ソート

↑ページトップへ

#ASCII
my @res = sort @list;
#数値
my @res = sort {$a <=> $b} @list;
#数値逆順
my @res = sort {$b <=> $a} @list;
#文字列
my @res = sort {$a cmp $b} @list;
#文字列逆順
my @res = sort {$b cmp $a} @list;
#インデックス値(ソート前の3番目はソート後には何番目?)
my @res = sort {$list[$a] <=> $list[$b]} 0 .. $#list;
#インデックス値(ソート前の3番目はソート後には何番目?)文字列
my @res = sort {$list[$a] cmp $list[$b]} 0 .. $#list;

ファイルを更新日時順にソート

↑ページトップへ

古い順

my $dir = '/Users/officek/Desktop/test';
$dir =~ s/\/$//;
opendir DIR, $dir;
my @files =
    map { $_->[0] }
    sort { $b->[1] <=> $a->[1] }
    map { [ $_, -M "$dir/$_" ] }
    grep ( /^[^.]/, readdir DIR );
close DIR;

for my $file(@files){
    my ($ss, $mm, $hh, $DD, $MM, $YY, $wday, $yday, $isdst) = localtime( ( stat qq|$dir/$file| )[9] );
    $YY += 1900;
    $MM ++;
    printf "%s\t%d-%02d-%02d %02d:%02d:%02d\n", $file, $YY, $MM, $DD, $hh, $mm, $ss;
}

新しい順

    sort { $a->[1] <=> $b->[1] }

変数

↑ページトップへ

#Perlのバージョン(バージョン+パッチレベル/100)
#use Englishした場合は、$PERL_VERSIONでアクセス可能。
$]
#マッチング
$`(前)←$&(そのもの)→$'(後)
#実行中のファイル名
$0

マッチング

↑ページトップへ

#後ろタブのある単語にマッチ($&にタブは含まれない)
/\w+(?=\t)/
#後ろにbarがないfooにマッチ
/foo(?!bar)/
#グループ化(後方参照用に記憶される)
/Windows (Me|Xp)/
#後方参照を行なわないグループ化
/Windows (?:Me|Xp)/
($year, $month, $day) = (/^(\d\d\d\d)(\d\d)(\d\d)$/);
#下記よりも
/a|b|c/
#下記の方が高速
/[abc]/
#マッチしたものが配列に入る
my @match = ($text =〜 /^(\d+)\-(\d+)\-(\d+)$/);
#マッチした個数(例: タブの個数)
my $count = ($text =~ tr/\t/\t/);

進数変換

↑ページトップへ

#16進数→10進数
$dec = hex( 0x1AB );
#10進数→16進数
$hex = sprintf("%lx", 16);
#10進数→8進数
$oct = sprintf("%lo", 10);
#8進数→10進数
$dec = oct 10;

情報

↑ページトップへ

#バージョン/パッチ情報等
$ perl -v
#モジュール検索
find `perl -e 'print "@INC"'` -name '*.pm' -print
find `perl -e 'print "@INC"'` -name 'Jcode.pm' -print

特殊リテラル

↑ページトップへ

#プログラムの論理的な終わり(この文字列以降は解釈されない)
__END__
#現在のファイル名
__FILE__
#現在の行番号
__LINE__
#現在のパッケージ名
__PACKAGE__

__END__以降の行は<DATA>で読み込むことができる。

読み込み

↑ページトップへ

#localで局所化して一気に読み込み
my $dat;
open IN, "<$in" or die "cat not open: $!";
{local $/; $dat = <IN>; }
close DAT;

リファレンス

↑ページトップへ

調べる

ref $aaa;
#返り値→SCALAR / CODE / ARRAY / HASH

スカラーのリファレンス/デリファレンス

#$scalar
my $ref = \$scalar;
#\$scalarのデリファレンス
${$ref}; $$ref;

配列のリファレンス/デリファレンス

#@aryのリファレンス
my $ref = \@ary;
#\@aryのデリファレンス
@{$ref}; @$ref;
#配列の要素へアクセス
${$ref}[1]; $$item[1]; $ref->[1];
#2次元、3次元なら
$ref->[1]->[3]->[0];

ハッシュのリファレンス/デリファレンス

#%hashのリファレンス
my $ref = \%hash;
#デリファレンス
my $name = ${$ref}{'name'}; $$ref{'name'}; $ref->{'name'};
#ハッシュ全体
my @key = keys %{$ref}; %$ref;

サブルーチンのリファレンス/デリファレンス

#⊂のリファレンス
$ref = \⊂
#デリファレンス
&{$ref}('yugo');
&$ref('yugo');
$ref->('yugo');

無名配列

my $fruits = ['pineapple', 'papaya', 'mango'];
#下記と同義
my $fruits;
{
 my @secret_variable = ('pineapple', 'papaya', 'mango');
 $fruits = \@secret_variable;
}

無名ハッシュ

my $ref_to_yugo_info = {
 name => 'yugo',
 hat => 'White',
 shirt => 'Red',
};
#下記と同義
my $ref_to_yugo_info;
{
 my %yugo_info = (
 name => 'yugo',
 hat => 'White',
 shirt => 'Red',
 );
 $ref_to_yugo_info = \%yugo_info;
}

無名サブルーチン

my $ref_sum = sub{
  my $total;
  for my $num(@_){
    $total += $num
  }
  return $total;
}
#使う
my $total = $ref_sum->( 1, 2, 3 );

リファレンスの中身

use Data::Dumper;
#リファレンスを渡す
print Dumper($ref);
#utf8対応
use Data::Dumper;
{ no warnings; package Data::Dumper; sub qquote { return shift; } }
$Data::Dumper::Useperl = 1;
print Dumper $k;

複数行コメントアウト

=for comment
コメントアウトされる
=cut

utf8対応

use strict;
use warnings;
#ソースがutf8
use utf8;
use Encode;
#IN/OUTをutf8
use open IO => ":utf8";
#標準出力をutf8
binmode STDOUT, ":utf8";

継承

use base qw/Yugo::Common Yugo::Html/;

メソッドのオーバーライド

sub speak{
    my $class = shift;
    $class->SUPER::speak(@_);
}

constant

use constant LIB_DIR => '/home/yugo/lib';
use lib LIB_DIR;

Perl with Macintiosh メモ

↑ページトップへ

use Text::Iconv;

my $path = $ARGV[0];
#特殊なNFDなUTFから通常のUTF-8へ
my $path_nfc = Text::Iconv->new('UTF-8-MAC', 'UTF-8')->convert($path);
#UTF-8フラグが落ちてしまったので、再度たてる
my $path_nfc_flagged = Encode::decode('UTF-8', $path_nfc);

#まとめると以下
#$path = Encode::decode('UTF-8', Text::Iconv->new('UTF-8-MAC', 'UTF-8')->convert($path));

Windows ActivePerl メモ

↑ページトップへ

ファイルの入出力は、UTF-8/LFにしたい。
ソースファイルは当然UTF-8にしたい。

use strict;
use utf8;
use open IO => ":unix:utf8"; #:unixでLFに、:utf8でUTF-8に。
binmode STDIN,  ":crlf:encoding(cp932)";
binmode STDOUT, ":crlf:encoding(cp932)";
binmode STDERR, ":crlf:encoding(cp932)";

binmodeの指定は以下のようにしても。

map { binmode($_, ":crlf:encoding(cp932)") } qw/STDIN STDOUT STDERR/;

デバッグ

↑ページトップへ

# 起動
perl -d test.pl
# ブレークポイント
$DB::single = 1;
# 条件付ブレークポイント
if ($num == 2) { $DB::single = 1 }
# 警告をキャッチしてブレークポイントしかける
$SIG{__WARN__} = sub {
    $DB::single = 1;
};
  • q : 終了
  • n: 次の行実行
  • s: 次のステップ実行(サブルーチンの中も)
  • c: ブレークポイントまで実行
  • c 5: 5行目の直前まで実行
  • p $num: 変数の中身を表示
  • x \%hash: 変数の中身を表示(リファレンス渡し)
  • v: 周辺の行を表示
  • .: 現在の行を表示
  • (任意の文を実行させることも可能)

ホスト名の取得

↑ページトップへ

use Sys::Hostname qw/hostname/;

my $host = hostname();

↑ページトップへ