Perl: 2008年3月アーカイブ

年月日 → 曜日 に変換する関数です。

sub get_week{
  my($y,$m,$d);
  if(@_ == 3){
    ($y,$m,$d) = @_;
  }elsif(@_ == 1){
    ($y,$m,$d) = split /-/, $_[0];
  }
  my @wdays = qw(日 月 火 水 木 金 土);
  if ($m < 3) {$y--; $m+=12;}
  my $w=($y+int($y/4)-int($y/100)+int($y/400)+int((13*$m+8)/5)+$d)%7;
  return $wdays[$w];
}

使い方

 my $week = get_week(2008,3,21);  # "金"
または、
my $week = get_week("2008-3-21");
my $week = get_week("2008-03-21");


Googleで検索しまくると、実にいろんなやり方が出てくる。

  • ファイルの中身を全部一気に変数に入れて、改行コードを数える
  • ファイルの中身を一括で配列に入れて、要素数を数える
  • ファイルの中身を一行ずつ読み込んで、行数をカウント
  • ファイルを最後まで読み込んで、$.を参照する

結局いろんな人のいろんなやり方を見たあげく、
perlfaq5に公式(?)のやり方が載っているのに気づいた。

    $lines = 0;
    open(FILE, $filename) or die "Can't open `$filename': $!";
    while (sysread FILE, $buffer, 4096) {
        $lines += ($buffer =~ tr/\n//);
    }
    close FILE;

どれが一番速いのかはわかりません。。。

参考:
例えば、
log20080308.txt
   ↓
log-2008-03-08.txt
のように、 フォルダ内のファイル名を全部いっぺんに変更したいとき。

for (glob("log*.txt")) {
	my $old_name = $_;
	s/(^.+)([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).txt/$1-$2-$3-$4.txt/;
	my $new_name = $_;
	rename $old_name, $new_name;
}

参考:Perlでファイル名を変更(リネーム)するにはrename
rename "変更前のファイル名", "変更後のファイル名";

例: foo.txt → bar.txt に変更

rename "foo.txt", "bar.txt";

ワンライナーで

perl -e "rename 'foo.txt', 'bar.txt'"

関連記事:Perlで、フォルダ内のファイル名を一括変更するには
1 → 001 のように、数字の左側をゼロで埋めたい場合がよくあります。
下記のように書くと便利です。
$a = 1;
$b = sprintf("%03d",$a);
print $b;  #  →  "001"と出力
出力する桁数をパラメータで動的に指定したい場合は、
$keta = 3;  # 桁数を指定
$a = 1;
$b = sprintf("%0".$keta."d", $a);
print $b;   # →  "001"と出力
自作関数でpadd_zero()みたいなのを作ってもいいのですが、
使い捨てスクリプトを急いで書く場合は、上記のやり方が便利です。

プログラムを書いていて、下記のように配列を初期化することがよくあります。

配列 = [
要素1,
要素2,
];

このときいつもモヤモヤするのが、

最後の要素の後にカンマ(,)付けても大丈夫なんだっけ?

ということ。
つまり、この配列は要素が2個としてちゃんと解釈されるのかな?という不安です。


よい機会なので、JavaScript、PHP、Perlで挙動の違いをまとめてみました。

Perlの場合

@ary = ("foo", "bar",);
$count = @ary;
print $count;
→ 結果  2

PHPの場合
$ary = array( "foo", "bar", );
echo count($ary);
→ 結果  2

JavaScript (Firefox) の場合
var ary = ["foo","bar",];
alert(ary.length);
→ 結果 : 2

JavaScript (IE6) の場合
var ary = ["foo","bar",];
alert(ary.length);
→ 結果 : 3

結論。

IEのJavaScriptI(=JScript)は、最後のカンマのあとにもう一つ空の要素を生成する。


というわけで本日のまとめ。


 [FOO,BAR,] を

 3個と数える

 JScript


字あまり ><

foreachを使ってますか?

初級プログラマに意外と知られていないforeach。

何が便利かというと、
カウンタや添え字(index)を意識せずに、配列の要素に対してアクセスし、何らかの処理をすることができます。

foreachを使わない場合、

for(i=0;i<=n;i++){ print 配列名[i]; }
のように、配列の要素数とカウンタを使ったダサイ記述をするハメになります。
一方、foreachを使えば楽ができます。

私はこのforeachが大好きです。
foreachのおかげで、配列が好きになりました。

以下、Perl , PHP, VBA, JavaScriptで、配列の全要素を表示する例です。

Perl  
foreach my $item (@items) { print $item; }
PHP
foreach ( $items as $item){ echo $item; }
JavaScript
for(var i in items){ alert(items[i]);}
VBA  
For Each item In items
  MsgBox item
Next


※注1 Perlの場合は、さらに短く書けます。
foreach (@items){ print $_ ;}  または
for(@items){ print $_;}      または
print for @items; 

※注2 VBAのこのコードは、厳密にはコレクションといって、配列とは別のものです。 しかし実質的には配列のように使えます。

このアーカイブについて

このページには、2008年3月以降に書かれたブログ記事のうちPerlカテゴリに属しているものが含まれています。

前のアーカイブはPerl: 2008年2月です。

次のアーカイブはPerl: 2008年5月です。