サンプルというかコード覚え書き

文字と進数変換

# 文字 N = 10進数78 = 16進数4e = 8進数116 = 2進数01001110

# 先頭の英大文字が一番手間のかからない変換手順

文字⇔数値

# 文字→数値
print "N -> ".ord('N')."\n";
print "N -> ".unpack("C*",'N')."\n";
# 数値→文字
print "78 -> ".chr(78)."\n";
print "78 -> ".pack("C*",78)."\n";
  • 実行結果
    N -> 78
    N -> 78
    78 -> N
    78 -> N

16進数⇔10進数

# 16進数→10進数
print "4e -> ".hex('4e')."\n";                       
print "4e -> ".unpack('C*',pack('H*','4e'))."\n";
# 10進数→16進数
print "78 -> ".sprintf("%x",78)."\n";    
print "78 -> ".unpack('H*',pack('C*',78))."\n";
  • 実行結果
    4e -> 78
    4e -> 78
    78 -> 4e
    78 -> 4e

16進数⇔2進数

# 16進数→2進数
print "78-> ".unpack('B*',pack('H*','78')); # 78を指定しても10進数の78とは解釈されない
# 2進数→16進数
print "01111000-> ".unpack('H*',pack('B*','01111000'));
  • 実行結果
    78->01111000
    01111000->78

16進数⇔文字

# 16進数→文字
print "4e -> ".pack('H*','4e')."\n";
print "4e -> ".chr(hex('4e'))."\n";
# 文字→16進数
print "N -> ".unpack("H*",'N')."\n";
print "N -> ".sprintf("%x",ord('N'))."\n";
  • 実行結果
    4e -> N
    4e -> N
    N -> 4e
    N -> 4e

8進数⇔10進数

# 8進数→10進数
print "116-> ".oct('116')."\n";
# 10進数→8進数
print "78 -> ".sprintf("%o",78)."\n";
  • 実行結果
    116-> 78
    78 -> 116

リファレンスのテスト

#配列@arrayにハッシュ領域確保
push(@array,{a=>A},{b=>B});
#スカラー変数$arrayに配列領域確保、その中にハッシュ領域確保
$array = [ {a=>'A+'},{b=>'B+'} ];

print <<"EOM";
//// {a=>A},{b=>B} のリファ ////
\@array	= @array

//// {a=>A} のリファ ////
\$array[0]	= $array[0]

//// {a=>A} の内容 ////
\$array[0]->{a}		= $array[0]->{a}
\$array[0]{a}		= $array[0]{a}
\${\$array[0]}{a}		= ${$array[0]}{a}

//// [ {a=>'A+'},{b=>'B+'} ] のリファ ////
\$array			= $array

//// \$arrayの指す配列 {a=>'A+'},{b=>'B+'} のリファ ////
\@\$array			= @$array
\@{\$array}			= @{$array}
//// {a=>'A+'} のリファ ////
\$array->[0]		= $array->[0]
\$\$array[0]			= $$array[0]
\${\$array}[0]		= ${$array}[0]

//// {a=>'A+'} の内容 ////
\$array->[0]->{a}		= $array->[0]->{a}
\$array->[0]{a}		= $array->[0]{a}
\$\$array[0]->{a}		= $$array[0]->{a}
\$\$array[0]{a}		= $$array[0]{a}
\${\$array}[0]->{a}		= ${$array}[0]->{a}
\${\$array}[0]{a}		= ${$array}[0]{a}
EOM

# \${\$array}		= ${$array}\n";	# $array が SCALAR 型でないのでエラーになる
# \$\$array			= $$array\n";	#  〃
  • 実行結果
    //// {a=>A},{b=>B} のリファ ////
    @array	= HASH(0x1625028) HASH(0x1625100)
    
    //// {a=>A} のリファ ////
    $array[0]	= HASH(0x1625028)
    
    //// {a=>A} の内容 ////
    $array[0]->{a}		= A
    $array[0]{a}		= A
    ${$array[0]}{a}		= A
    
    //// [ {a=>'A+'},{b=>'B+'} ] のリファ ////
    $array			= ARRAY(0x3d93c)
    
    //// $arrayの指す配列 {a=>'A+'},{b=>'B+'} のリファ ////
    @$array			= HASH(0x16250e8) HASH(0x3d918)
    @{$array}			= HASH(0x16250e8) HASH(0x3d918)
    //// {a=>'A+'} のリファ ////
    $array->[0]		= HASH(0x16250e8)
    $$array[0]			= HASH(0x16250e8)
    ${$array}[0]		= HASH(0x16250e8)
    
    //// {a=>'A+'} の内容 ////
    $array->[0]->{a}		= A+
    $array->[0]{a}		= A+
    $$array[0]->{a}		= A+
    $$array[0]{a}		= A+
    ${$array}[0]->{a}		= A+
    ${$array}[0]{a}		= A+

配列の内容をランダム順にする

@x = 'a'..'f';
@y = &array_shuffle(@x);

print "x:".join(' ',@x)."\n";
print "y:".join(' ',@y)."\n";

# 与えられた配列の順番をランダムにした配列を返す
sub array_shuffle{
	my @list = @_;
	my @list2;
	while($#list >= 0){
		push(@list2, splice(@list,int rand($#list + 1),1));
	}
	@list2;
}
  • 実行結果
    x:a b c d e f
    y:a d c f b e

文字列を文字単位で配列に分割(半角全角含)

半角、全角文字を1文字ずつ分割して配列に格納する。
ただし文字コードは必ずEUCであること。
調べてないけど今ならモジュールでもできそう。

use Jcode; 
$x = jcode('電人HAL')->euc;    #EUCに変換
@y = splitchar($x);
foreach $z (@y){
	print jcode("$z\n")->sjis;  # 表示用にsjisに変換
}
# 文字列を文字単位に分割する(EUC限定)
# \x8F[\xA1-\xFE][\xA1-\xFE]    3バイトコード
# [\x8E\xA1-\xFE][\xA1-\xFE]    2バイトコード
# [\x00-\x7F]                   1バイト(アスキー)コード
sub splitchar{
	my $str = shift;
	$str =~ /\x8F[\xA1-\xFE][\xA1-\xFE]|[\x8E\xA1-\xFE][\xA1-\xFE]|[\x00-\x7F]/og;
}
  • 実行結果
    電
    人
    H
    A
    L

メタ文字エスケープ

$x = '<HR>Love & Peace!<HR>';
$y = &metaescape($x);
$z = &metaunescape($y);
print "x:$x\n";
print "y:$y\n";
print "z:$z\n";

#-----------------------------------------------------------
# HTMLの特殊文字をエスケープする
#-----------------------------------------------------------
sub metaescape{
	my $str = shift;
	$str =~ s/&/&amp;/g;	# &は最初にエスケープしないと他が化ける
	$str =~ s/</&lt;/g;	# 
	$str =~ s/>/&gt;/g;	# 
	$str =~ s/"/&quot;/g;	# 
	$str =~ s/ /&nbsp;/g;	# 連続しても圧縮されない空白文字
	$str;
}
#-----------------------------------------------------------
# HTMLの特殊文字を戻す。
# ただし元通りにはならないかもしれない。
#-----------------------------------------------------------
sub metaunescape{
	my $str = shift;
	$str =~ s/&amp;?/&/g;
	$str =~ s/&lt;?/</g;
	$str =~ s/&gt;?/>/g;
	$str =~ s/&quot;?/"/g;
	$str =~ s/&nbsp;?/ /g;
	$str;
}
  • 実行結果
    x:<SPAN STYLE="color: red">Love & Peace!</SPAN>
    y:&lt;SPAN&nbsp;STYLE=&quot;color:&nbsp;red&quot;&gt;Love&nbsp;&nbsp;&amp;&nbsp;&nbsp;Peace!&lt;/SPAN&gt;
    z:<SPAN STYLE="color: red">Love & Peace!</SPAN>

fork プロセスの分割

  • 親と子に処理を分割する。
  • 返り値が0なら子プロセス、!0ならプロセスIDの入った親プロセスとなる。
    これが実行された時点で処理が2つに分岐しおのおので継続する。
    親と子それぞれの処理を区別するには返り値を参照する。
    子プロセスは間違って親プロセスまで実行してしまわないように
    処理が済んだら exit で終了させておくこと。
    # 実行すると2秒後に I am Child.
    # その2秒後に I am Parent. を表示する。
    print "fork start\n";
    if( ($pid = fork()) == 0 ){	#子プロセス
    	sleep(2);					#2秒待機
    	print "I am Child.\n";
    	exit;
    }else{							#親プロセス
    	sleep(4);					#4秒待機
    	print "I am Parent.\n";
    }

Windows系でのクリップボード操作

use Win32::Clipboard;
$cb = Win32::Clipboard();
$cb->Set('ABCDEFG');	#クリップボードに送る
$data = $cb->Get();	#クリップボードから取得

まとめてできる操作はなるべく使って手抜きをするのだ

配列

書式意味
scalar(@ARRAY)配列 @ARRAY の要素数。隙間なく詰まっているなら
$#ARRAY+1 == scalar(@ARRAY)
になるが間の要素が抜けていることもある
要素が無い場合は 0
$#ARRAY配列 @ARRAY の末尾の要素の添え字。要素が無い場合は -1
$ARRAY[$#ARRAY]配列 @ARRAY の末尾の要素
$ARRAY[0]配列 @ARRAY の先頭の要素
@ARRAY = ('A' .. 'Z')配列の実体を取得
@ARRAY2 = @ARRAY配列の内容をコピー
$ARRAY[2]2番目の配列の内容を取得
@ARRAY[0,2]配列のスライス。
0番目と2番目の要素だけを抜き出す

カンマ演算子

  • m .. n の左から右までの連続する配列を生成するカンマ演算子。
    左から右へは昇順になる必要があり、降順にすると生成できない。
    降順の連続する配列を作るなら昇順にしたものに reverse で反転させる。
    文字列も扱えるが半角の英数字を大文字・小文字を合わせて使ったほうがよさそう。
  • カンマ演算子は代入演算子より優先順位が低いため
    @ARRAY = 1 .. 5; だと 1 が先に代入されてしまうので必ず括弧でくくる。
    書式意味
    ( 3 .. 6 )3から6への連続する整数配列(3,4,5,6)
    ( -2 .. 2 )-2から2への連続する整数配列(-2,-1,0,1,2)
    ( 'm' .. 'o' )mからoへの連続する文字配列('m','n','o')
    ( 'M' .. 'O' )MからOへの連続する文字配列('M','N','O')
    ( 'ok' .. 'on' )okからonへの連続する文字列配列('ok','ol','om','on')
    ( 'm' .. 'O' )mからzへの連続する文字配列。終端のOが認識されていないようでzまでいってる。
    期待通りの結果が出るかわからないのでやらないほうがよい
    ( 'M' .. 'o' )MからZへの連続する文字配列。
    終端のoが認識されていないようでZまでいってる。
    同上
    ( 'ok' .. 'ON' )okからzzへの連続する文字列配列。同上
  • カンマ演算子を降順に取得
    @r = reverse(1..8); # (8..1) では取得できない

配列の部分取り出し(配列のスライス)

書式意味
@ARRAY[1,2,4,8]配列内の 1,2,4,8 番目を取り出す
@ARRAY[2,4,1,8]上のを順番をばらばらに取得することもできる
@ARRAY[2,2,2,2]あまり意味はないが2番目だけを何個も取得することもできる
@ARRAY[2 .. 4]配列内 2 から 4 番目を取り出す
@ARRAY[reverse(2 .. 4)]配列内 4 から 2 番目を取り出す
@ARRAY[0 .. $#ARRAY]全内容を取り出す。つうか @ARRAY と同じはず

push, pop, shift, unshift

$a = pop(@ARRAY); # 配列の最後尾を返して、配列から削除
$a = shift(@ARRAY); # 配列の先頭を返して、配列から削除
push(@ARRAY,@a); # 配列の最後尾に追加
unshift(@ARRAY,@a); # 配列の先頭に追加

splice - 基本

splice( @ARRAY, $OFFSET, $LENGTH, @LIST );

  • 配列操作を一括してやってくれる。
    $OFFSET からの配列要素を $LENGTH 個抜き出してから、
    $OFFSET に新たな配列要素@LISTを追加する
    • $OFFSET
      要素の取り出し、挿入の基点となるオフセット。
      0 なら先頭を示し、$#ARRAY なら末尾を示す。
      また負の値 -1 からでも末尾を示し、以降-2で末尾の1つ前の要素というように逆順に示すこともできる。
      push のような「末尾+1」に挿入したければオフセットに $#ARRAY+1 を使う。
      オフセットが -0 では 0 と同様になる。

    • $LENGTH
      $ARRAY[$OFFSET] 以降から抜き出す要素の個数を返す。
      0 ならば抜き出さない。
      splice(@ARRAY,1);のように省略するとオフセット以降の全てを抜き出す。
      shiftやpopと同様に、spliceで抜き出した要素はその配列から消える。
      # 以下の2つは@a,@bに入る値は同じだが、@ARRAYに要素を残すか削るかが違う。
      @ARRAY = ('a'..'f');
      @a = @ARRAY[0..3];		# 要素を残す @ARRAY = ('a','b','c','d','e','f');
      @ARRAY = ('a'..'f');
      @b = splice(@ARRAY,0,3);	# 要素そ削る @ARRAY = ('d','e','f');
      $OFFSETが正の値のときに$LENGTHを負の値にするとオフセット以降を-n個残すように抜き出す。
      # $ARRAY[4]から末尾までの6個を抜き出す。
      # [4]以降が6個以下ならあるだけ抜き出す。
      splice(@ARRAY,4,-6);

    • @LIST
      $ARRAY[$OFFSET] 以降に挿入する要素のリスト。
      何も指定しなければ挿入しない。
      splice(@ARRAY,0,0,@a);	# unshift(@ARRAY,@a) と同様
      splice(@ARRAY,0,1);		# shift(@ARRAY) と同様
      splice(@ARRAY,$#ARRAY+1,0,@a);	# push(@ARRAY,@a) と同様
      splice(@ARRAY,-1,1);		# pop(@ARRAY) と同様

splice - 配列要素を任意の位置に挿入する

@ARRAY = ('a'..'f');
splice(@ARRAY,3,0,'Z');
print @ARRAY;
  • 実行結果
    abcZdef

splice - 配列要素を任意の範囲から抜き出す

# 3番目から 2個抜き出す
@ARRAY = ('a'..'f');
splice(@ARRAY,3,2);
print @ARRAY;
  • 実行結果
    abcf
# 3番目以降全て抜き出す
@ARRAY = ('a'..'f');
splice(@ARRAY,3);
print @ARRAY;
  • 実行結果
    abc

splice - 配列要素を任意の数に切り詰める

#先頭から3文字に切り詰める
@ARRAY = ('a'..'f');
splice(@ARRAY,3);
print @ARRAY;
  • 実行結果
    abc
#末尾から3文字に切り詰める
@ARRAY = ('a'..'f');
splice(@ARRAY,0,-3);
print @ARRAY;
  • 実行結果
    def
#先頭1文字と末尾2文字に切り詰める
@ARRAY = ('a'..'f');
splice(@ARRAY,1,-2);
print @ARRAY;
  • 実行結果
    aef

連想配列(ハッシュ)

書式意味
keys %HASH%HASH のキーが入った配列
values %HASH%HASH の内容が入った配列
%HASH = ('A','a','B','b','C','c')ハッシュの実体を取得。前をキー名、後を内容とする
%HASH = ('A'=>'a','B'=>'b','C'=>'c')同上。こっちのほうが参照先がわかりやすい
$HASH{'C'}キー名 C の内容を取得
@HASH{'A','C'}ハッシュのスライス('a','c')

参照渡し(リファレンス)

リファレンスは変数の入れ物の場所を表す一種のメモリアドレス。
C言語でいうポインタのような処理ができる(厳密には違うが)ので
多次元配列やリファのリファのような扱いができる。

書式意味
$s = ¥$SCALAR
$a = ¥@ARRAY
$h = ¥%HASH
$c = ¥&CODE
それぞれの変数の型のリファ
$$s
@$a $$a[0]
%$h $$h{'A'}
&$c
リファの指す実体
ref(¥$SCALAR)
ref(¥@ARRAY)
ref(¥%HASH)
ref(¥&CODE)
リファが示す変数の型を判定、
SCALAR,ARRAY,HASH,GLOBなどを返す。
データがリファでなく要素そのものなら未定義値
$array = ['A','B','C']
$array = [ ]
配列を確保し、そこのリファを取得
$$array[2]
$array->[2]
リファが示す配列の2番目の要素
@ARRAY = @{ {'A','B','C'} }
@ARRAY = @$array
リファが示す配列の全要素
$hash = {'A'=>'a','B'=>'b','C'=>'c'}
$hash = { }
ハッシュを確保し、そこのリファを取得
$$hash{'C'}リファが示すハッシュのキー名 C の要素
%HASH = %{ {'A'=>'a','B'=>'b'} }
%HASH = %$hash
リファが示すハッシュの全要素
${ {'A'=>'a','B'=>'b'} }{'B'}定義から直接キー名 C の内容を取得
@{ {'A'=>'a','B'=>'b''} }{'B','A'}ハッシュのスライス('a','c')

sendmail

#サーバごとのsendmailパスを記述
$SENDMAIL_CMD = '/usr/bin/sendmail';

&sendmail('foo@bar.com', 'testmessage');

# メールアドレスにメッセージを送信
#
# JISに変換してないので個別にやる必要あり
sub sendmail{
	my $addr = shift;
	my $msg  = shift;

	open(MAIL,'|'.$SENDMAIL_CMD.' '.$addr) || return 0;
	print MAIL $msg;
	close(MAIL);
	return 1;
}

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規新規下位 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-06-06 (金) 04:08:13 (3305d)