1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Perlメモ

Last updated at Posted at 2022-12-15

最近またPerlを使い始めたのでメモを残す。

関数

概要 関数 返却値
置換 $x =~ tr/検索/置換/ 左辺を変更
部分文字列 substr($文字列, 開始, 長さ) 部分文字列。開始、長さは文字数
文字列分割 split(/区切り/, 文字列, 分割最大数) 分割結果を要素とするリスト(配列)
関数名(自分) (caller 0)[3] 自身の関数名。
関数名(call元) (caller 1)[3] call元の関数名。
call元 ($caller1P, $caller1F, $caller1L) = caller call元の(PKG名, ファイル名, 行数)
バイナリを16進文字列 $hexstr = unpack("H*", $hexval) バイナリREADの結果($hexval)を16進文字列に
16進文字列をバイナリ $hexval = pack("H*", $hexstr) 16進文字列をバイナリWRITE

エンコード・デコード

ソース・STDOUT,STDERR

use utf8;           # スクリプト内の文字を、UTF8 -> 内部コードに変換する
binmode STDOUT, ":utf8" ;
binmode STDERR, ":utf8" ;

文字コードを指定して、テキストファイルをオープンする

open my $fh, "<:encoding($dec)", $fname ;
open my $fh, ">:encoding($enc)", $fname ;

ファイルハンドルから入力と、CRLFの削除

while( my $line = <$gInf_fh> ) {
	chomp($line);	# 改行コードLFを削除
	if(substr($line, length($line) - 1, 1) eq "\r") {	# CRがあれば削除
		chop($line);
	}
}

バイナリファイルを読み込み、16進文字列にunpackする

my	$ret	= read $fh, $hexval, $lrecl;	# ファイルをlreclバイトREAD
if(defined($ret)) {
	$hexstr	= unpack("H*", $hexval);		# InternalVal to hex-str(dump)
	$hexstr	=~	tr/a-f/A-F/;
	if($ret == 0) {					# EOF検知
		$$rec	=	$hexstr;		#   recにHEX文字列を設定して
		return $EOF;}				#   EOFをリターン
	elsif($ret > 0) {				# 正常READ
		;
	}
} else {
	&dbglog($Msglevel{"ERR"}, "$myname,IO-ERR:$recfm($fname)");
	return $EOF;
}

16進文字列を、バイナリにpackしてファイルに書き込む

if($fname eq '')	{ print STDOUT pack("H*", $rec);}

モジュール分割

起動スクリプトを同ディレクトリの、別ファイルをインポートする

my  $dirname0 = dirname $0;
require "$dirname0" . "/subfile.pl" ;

デバックテクニック

DBGLOG関数

my  $Loglevel   = 2;    # output loglevel
our @Msgtag = ("ALL", "CRI", "ERR", "WRN", "INF", "DBG", "FNC", "LV7");
our %Msglevel = (ALL => 0, CRI => 1, ERR => 2, WRN => 3, INF => 4, DBG => 5, FNC => 6, LV7 => 7 ) ;
sub setLoglevel { return ($Loglevel = $_[0]); }
sub getLoglevel { return $Loglevel; }

sub	dbglog {
	my	($msglevel, @msg)	=	@_;
#
	my	$myName		= (caller 0)[3];
	my	($caller1P, $caller1F, $caller1L) = caller();
	my	$caller1N = (caller 1)[3];
	my	$caller2N;
	if((caller 2)[3]){$caller2N = (caller 2)[3];}else{$caller2N	= "";}
#
	if( ! defined($msglevel) ) {
		die "!!DIE msglevel notdefined, CALLED=$caller1N,FILE=$caller1F,LINE=$caller1L:$!";
	} elsif( $msglevel eq "") {
		die "!!DIE msglevel($msglevel) is null, CALLED=$caller1N,FILE=$caller1F,LINE=$caller1L:$!";
	}

	($msglevel > 7 || $msglevel < 0) && die "!!DIE msglevel invalid:$msglevel:$!";
	if($msglevel <= $Loglevel) {
		foreach my $msg(@msg) {
            if($msglevel eq $Msglevel{'ALL'}) {
                printf STDERR ("!!%s:%s:%s\n", $Msgtag[$msglevel], "", $msg);
            } else {
                printf STDERR ("!!%s:%s:%s\n", $Msgtag[$msglevel], "$caller1N($caller2N),$caller1F:$caller1L" ,$msg);
            }
		}	
	}
	return $TRUE;
}

my $myname = (caller 0)[3]
&dbglog($Msglevel{'ALL'}, ("MSG1", "MSG2"));
&dbglog($Msglevel{'ERR'}, "$myname,err ot_recfm:$otrecfm");
pri loglevel 処理継続 用途
ALL 0 JOB開始、終了
CRI 1 × 即時、die
ERR 2 × 終了処理をして、ABENDする
WRN 3 エラー回復して、処理継続
INF 4 処理状況
DBG 5 デバック出力
FNC 6 詳細なデバッグ
LV7 7 (未定義)

ERR-MSGの統一

our %Errcd = (NUM => 'ERR(NUM)', FILE => 'ERR(FIL)');
&dbglog($Msglevel{'ERR'}, "$myname,$Errcd{FIL}:not found:$fname");

その他

構造体

  • 構造体の定義
use	Class::Struct ;
struct	Fctrl => {
	fname	=> '$',		# ファイル名
	recfm	=> '$',		# F|V|T
	lrecl	=> '$',		# recfm=F:レコード長さ recfm=V:無効 recfm=T:無効
	isopened	=> '$',	# オープンされているか
	iocnt	=> '$',		# 入出力件数
	decenc	=> '$',		# ファイルのデコード(入力時)、エンコード(出力時)
	fh		=> '$'		# File Handle
} ;

  • 構造体のインスタンス化と値設定
my $Otfile = Fctrl->new();		# $Otfileはリファレンス型として定義されている
$Otfile->fname( 'FNAME' );		# 値の設定

sub	setDCB {
	my	($ref, $fname, $recfm, $lrecl, $decenc)	=	@_;
	if(defined($fname))	{ $ref->fname($fname);}
	if(defined($recfm)) { $ref->recfm($recfm);}
	if(defined($lrecl)) { $ref->lrecl($lrecl);}
	if(defined($decenc)){ $ref->decenc($decenc);}
	return $TRUE;
}

&setDCB($Otfile, 			# ref to Fctrl
	$cobfile::gOpt_otf,		# fname
	'T',					# recfm
	'',						# lrecl
	'utf8'					# encode
);

オプション

use Getopt::Long 'GetOptions';
our %gOpts = ();
GetOptions( \%gOpts,
  'recfm=s' ,
  'lrecl=i' ,
  'inf=s' , 
  'otf=s' ,
  'dmp=s' ,
  'edit=s' ,
  'logl=s' ,
  'req=s' ,
  'iferr=s' ,
  'help'
);

if( defined($gOpts{'help'}) ) {
	# --help 指定あり
} else {
	# --help 指定なし
}

配列の全要素を処理する、foreach

foreach my $msg(@msg) {
	print $msg;
}

ハッシュの全要素を処理する,

while(my ($key,$val) = each(%gOpts)) {
	print "$key = $val\n";
}

foreach my $key(keys(%gOpts)) {
	print $key;
	print $gOpts{$key};
}

foreach my $key(sort(keys(%Dbglog::Msglevel))) {
	print $key, "-", $Dbglog::Msglevel{ $key } , "\n";
}

ハッシュのハッシュ

hash_hashの要素が、[...]なので@{}でデリファレンス。

my	%hash_1 = (
	KEY1 => [0,2,'ZD','item11'], 
	KEY2 => [2,2,'BB','item12'], 
	KEY3 => [4,4,'PD','item13'],
	KEY4 => [8,4,'CH','item14']
);
my	%hash_2 = (
	KEY1 => [0,2,'ZD','item21'], 
	KEY2 => [2,2,'BL','item22'], 
	KEY3 => [4,4,'PD','item23'],
	KEY4 => [8,4,'CH','item24'],
	KEY5 => [12,8,'CH','item35']
);
our	%hash_for_hash = (
	KEYA => \%hash1, KEYB => \%hash2
);


my	$ref = \%hash_for_hash;
func( $ref );

sub	func {
	my	($ref_hash_hash) = @_;

	my	($st,$len,$type,$tag) = @{$ref_hash_hash->{'KEYA'}->{'KEY1'}};
}

ハッシュの先がアレイ

my @array1 = (
	[0,2,'ZD','item11'],
	[2,2,'BB','item12'], 
	[4,4,'PD','item13'],
	[8,4,'CH','item14']
);
my @array2 = (
	[0,2,'ZD','item21'],
	[2,2,'BL','item22'], 
	[4,4,'PD','item23'],
	[8,4,'CH','item24'],
	[12,8,'CH','item35']
);
our	%hash_for_array = (
	KEYA => \@array1, KEYB => \@array2
);

my	$ref = \%hash_for_array;
func( $ref );

sub func {
	my	($ref_hash_array) = @_;

	my	$ref_array = $ref_hash_array->{'KEYA'};
	my	@array = @{$ref_array};
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?