Perl再入門の最近のブログ記事

[Perl]DBIの使い方入門

PerlでDBIモジュールを使ってDB操作を行うためのかんたんなサンプルコードです。

「都道府県マスタ」テーブルを作って、CRUD(レコード追加、読み取り、変更、削除)を行います。

注:
  • コマンドラインから実行することを想定しています。
  • ユーザ名、パスワード、DB接続情報などは環境に合わせて変更してくださいね。
  • サンプルではMySQLを使用していますが、他のRDBMSにも使えると思います。

 #!/usr/bin/perl
 
 use strict;
 use warnings;
 use DBI;
 
 my $user = 'username';
 my $passwd = 'pass';
 my $host = 'localhost';
 my $dbname = 'mysample';
 my $dbh = DBI->connect("DBI:mysql:$dbname:".$host, $user, $passwd);
 
 my $sql;
 my $sth;
 
 # CREATE TABLE
 $sql = "CREATE TABLE prefmaster ( id INT , name VARCHAR(255) ) ";
 $dbh->do($sql);
 
 # INSERT
 $sql = " INSERT INTO prefmaster (id,name) values (1, 'hokkaido') ";
 $dbh->do($sql);
 $sql = " INSERT INTO prefmaster (id,name) values (2, 'akita') ";
 $dbh->do($sql);
 
 # SELECT
 $sql = "SELECT * FROM prefmaster";
 
 $sth = $dbh->prepare($sql);
 $sth->execute;
 
 print "SELECT\n";
 while(my @a = $sth->fetchrow_array){
     print "@a\n";
 }
 print "\n";
 
 # UPDATE
 $sql = " UPDATE prefmaster SET name = 'iwate' WHERE id = 2 ";
 $dbh->do($sql);
 
 # DELETE
 $sql = " DELETE FROM prefmaster WHERE id = 1 ";
 $dbh->do($sql);
 
 # SELECT AGAIN
 $sql = "SELECT * FROM prefmaster";
 
 $sth = $dbh->prepare($sql);
 $sth->execute;
 
 print "SELECT\n";
 while(my @a = $sth->fetchrow_array){
     print "@a\n";
 }
 print "\n";
 
 
 # DROP TABLE
 $sql = " DROP TABLE prefmaster ";
 $dbh->do($sql);
 
 
 $sth->finish;
 $dbh->disconnect;

ソースコードをUTF8で書いて、print文をUTF8で出力したい場合。

自分でもよく忘れるのでメモ。

#!/usr/bin/perl

use strict;
use warnings;
use utf8; # このスクリプトはUTF8で書かかれていますよ、という宣言

binmode STDOUT, ":encoding(utf8)";  # 以下のPrint文を自動的にUTF8として出力せよ、という命令

my $str ="あいうえお\n";
print substr($str,2,1)."\n;"    # 'う'  と出力される。

Perlでは、サブルーチンへのリファレンスを作って変数に格納することができます。

use strict;

sub greets {
print "hello\n";
}
my $ref = \&greets;

この例では、greetsサブルーチンへのリファレンスを、$refに格納しています。


デリファレンス

$refをデリファレンスして元のサブルーチンを呼び出す方法

まずおさらい。

普通のサブルーチン呼出はこう書きます。
 &greets();  # → hello 

ここで、
サブルーチン名 → {$ref}
と置き換えると、
$refをデリファレンスして元のサブルーチンを得ることができます。

&{ $ref }();  # → hello 

デリファレンスの省略記法

下記のコードはすべて同じ動作をします。

&{$ref}();
&$ref();
$ref->();

無名配列コンストラクタ [ ] を使って、ネストされたリファレンスを作ることができます。

例1
my $ref = [ [ 1, 2, 3 ] , [ 2, 4, 6 ] ] ;

これは、次のコードと同じような働きをします。
例2
my @array1 = ( 1, 2, 3 );
my @array2 = ( 2, 4, 6 );
my @array_all = ( \@array1, \@array2 );
my $ref = \@array_all;


デリファレンス
値を取り出すときはデリファレンスします。
print $ref->[1]->[1];   #  出力 4
または
print $ref->[1][1]; # 出力 4


2次元配列

上の例を見ると、2次元配列によく似ていることがわかると思います。
Perlではこのようにして2次元配列を実現します。

もちろん、ネストを重ねれば多次元配列を作れます。

例1
my $ref = [ 2, 4, 6 ]; 
これは、下記と同じような働きをします。

例2
my @array = ( 2, 4, 6 );

my $ref = \@array;


例2での@arrayに相当する中間変数が、例1にはありません。

このとき例1の$refには、「名前の無い配列」へのリファレンスが格納されています。

[ 2, 4, 6 ]における [ ]のことを
無名配列コンストラクタ
といいます。


参考: Perl再入門 | アルパカ本に学ぶリファレンス入門4 - 無名配列

use strict;

my @list = ("a", "b", "c");

my $ref = \@list;


# 配列全体を取り出す

print "@{$ref}\n"; # 出力: a b c

print "@$ref\n";   # 出力: a b c


# 配列の要素を取り出す

print "${$ref}[0]\n"; # 出力: a

print "$$ref[0]\n";   # 出力: a

print "$ref->[0]\n";  # 出力: a

省略のルール

  • { なんちゃら } が単純なスカラー変数の場合は、{ }を省略できる。
  • 例: @{ $ref }  ⇒  @$ref
       ${$ref}[0]  ⇒ $$ref[0]
  • ${ なんちゃら }[1] と書ける全てのコードは、なんちゃら->[1] と書ける。
  • 例: ${$ref}[0] ⇒ $ref->[0]

配列のリファレンスをネスト

リファレンスはネストさせることができます。
階層構造を持ったデータを作るときに便利です。

use strict;


my @array1 = (1, 2, 3);

my @array2 = (2, 4, 6);


my @all = (\@array1, \@array2);

my $ref = \@all;


# 値を取り出す

print "${${$ref}[1]}[2]\n";  # 出力: 6

print "$ref->[1]->[2]\n";    # 出力: 6

print "$ref->[1][2]\n";      # 出力: 6


# 配列を取り出す

print "@{${$ref}[1]}\n";  # 出力: 2 4 6

print "@{$ref->[1]}\n";   # 出力: 2 4 6
まず、@array1と@array2のリファレンスを作って@allに格納します。
次に、@allのリファレンスを作って$refに格納しています。

すると、$refは「配列のリファレンスを格納した配列」のリファレンス ということになります。

デリファレンスの省略記法

2つの法則があります。
  • ${なんちゃら}[1] と書ける全てのコードは、なんちゃら->[1] と書ける。
  • 添え字的なもの間に挟まれている矢印、つまり[1]->[2]とか{'foo'}->{'bar'}とかの矢印は省略できる。
${$ref}[1]  =>  $ref->[1]
$ref->[1]->[2]  => $ref->[1][2]
Perl再入門 | アルパカ本に学ぶリファレンス入門5  ネストした配列リファレンス

無名配列を作る

my $ref;

{
  my @array = (2, 4, 6);
  $ref = \@array;
}

print "@$ref";  # 出力: 2 4 6
@arrayはブロックが終わったときに消滅しますが、$refはブロックが終わっても値を保持します。

このとき、$refは、「名前の無い配列」への「リファレンス」を格納しています。
$refが参照している名前の無い配列を「無名配列」といいます。
($ref自体は「無名配列」への「リファレンス」です。)

値を取り出すときは、通常の配列リファレンスと同じようにデリファレンスします。
print $ref->[1];  # 出力 4

print "@$ref";    # 出力 2 4 6

無名配列へのリファレンスを作る

まず、通常の配列へのリファレンスを作る方法。
my @array = ( 2, 4, 6 );

my $ref = \@array;
一時変数(@array)をいちいち作るのはめんどくさいので、
下記のように書くこともできます。
my $ref = [ 2, 4, 6];
これを無名配列へのリファレンスといいます。

内部的には、無名の配列 (2, 4, 6)を作って、その配列へのリァレンスを作っています。
一時変数がなくなり、コードが読みやすくなりました。

値を取り出すときは、通常の配列リファレンスと同じようにデリファレンスします。
print $ref->[1];  # 出力 4

print "@$ref";    # 出力 2 4 6

リファレンスからデータの実体を取り出すことを、デリファレンスするといいます。

まずは配列。

リファレンス入門

Perl入門者がつまづきやすいリファレンスについて、続・初めてのPerl 改訂版(通称アルパカ本)を下敷きにしてわかりやすく解説してみます。

forとforeachは、何が違うのか?

実は、違いはありません。
まったく同じです。
リャマ本こと「初めてのPerl」の第10章にもこう書いてあります。

Perl文法の中では、キーワードforeachはキーワードforと完全に等価です。
つまり、プログラムの中で、forと書いてもforeachと書いても、Perlはそれを同じものとして扱うのです。


したがって、下記の2つのループは同じ動作をします。

use strict;
use warnings;

my @array = ("x", "y","z");

foreach(@array){
print $_."\n";
}

for(@array){
print $_."\n";
}

で、どちらを使えばよいのかというと、


文字数が少ないFORをお勧めします!
(ダジャレではない)

関連記事
Perl再入門 | 超簡単!for,foreachの使い方 Perl再入門 | for,foreachはループ対象の配列を書き換えます。ご注意。

配列に対してforやforeachでループ処理をする際に、制御変数の中身を変更すると、元の配列の中身も変更されてしまいます。


知らないと思わぬ損をするので、気をつけましょう。
私は今まで知りませんでした。(><)

use strict;
use warnings;

my @array = ("x", "y");

for (@array){
$_ = "z";
}

print "@array";

出力結果:
z z


なお、以下のような書き方でも同じ結果になります。
for my $a (@array){
$a = "z";
}

関連記事
Perl再入門 | 超簡単!for,foreachの使い方

forやforeachは、配列の全要素を対象としたループ処理をするときに使います。

人気記事

このアーカイブについて

このページには、過去に書かれたブログ記事のうちPerl再入門カテゴリに属しているものが含まれています。

前のカテゴリはPerlです。

次のカテゴリはPHPです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

最近の人気記事