Perlの最近のブログ記事
[JavaScript] 猿でもわかるクロージャ超入門という記事が好評だったので、今回はPerl編です。
上記のJavaScript版の記事を読んだという前提で解説させていただきます。
JS版とそっくりですね~。
関数のリファレンスを使っているので、呼び出し方法が$f->()のような形になっちゃいますが、そこはご愛嬌ということで。
これを利用すると、さらに短く書けます。
他にもいろいろ書き方があると思います。
Perlってサイコー!!
これらのモジュールでは、クロージャを使うことによってアクセサを実現しています。
上記のJavaScript版の記事を読んだという前提で解説させていただきます。
問題
呼び出すたびに、1,2,3,...を返すような関数f( )を定義せよ。f(); // 1
f(); // 2
f(); // 3
クロージャ その1
JS版のクロージャに似せて書くとこうなります。#!/usr/bin/perl
use strict;
use warnings;
sub outer {
my $i = 1;
return sub {
print "$i\n";
$i++;
};
}
my $f = outer();
$f->(); # 1
$f->(); # 2
$f->(); # 3
JS版とそっくりですね~。
関数のリファレンスを使っているので、呼び出し方法が$f->()のような形になっちゃいますが、そこはご愛嬌ということで。
クロージャ その2
JSと違ってPerlでは中カッコ{}でスコープを作ることができるので、より簡潔に書けます。#!/usr/bin/perl
use strict;
use warnings;
my $f;
{
my $i = 1;
$f = sub {
print "$i\n";
$i++;
};
}
$f->(); # 1
$f->(); # 2
$f->(); # 3
クロージャ その3
Perlではローカルスコープ内で宣言した関数を、スコープ外から参照することができます。これを利用すると、さらに短く書けます。
#!/usr/bin/perl
use strict;
use warnings;
{
my $i = 1;
sub f {
print "$i\n";
$i++;
}
}
f();
f();
f();
以上、Perlでのクロージャの作り方でした。他にもいろいろ書き方があると思います。
Perlってサイコー!!
クロージャの使われどころ
PerlにはClass::AccessorやClass::Data::Inheritablenaといった、オブジェクト指向をより便利にするための定番モジュールがあります。これらのモジュールでは、クロージャを使うことによってアクセサを実現しています。
参考
-
はてな匿名ダイアリー:PerlのClass::Data::Inheritableの解析
軽妙な語り口でClass::Data::Inheritableの実装を解説してくれる。もはやこれは文学だ。
Perl のクロージャ - naoyaのはてなダイアリー
クロージャの応用方法について深堀したい方はこちら。
PerlでDBIモジュールを使ってDB操作を行うためのかんたんなサンプルコードです。
「都道府県マスタ」テーブルを作って、CRUD(レコード追加、読み取り、変更、削除)を行います。
注:
「都道府県マスタ」テーブルを作って、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;
検索してこのページへたどり着いたあなたへ。
Perlの世界へようこそ。
use strict ワールドへようこそ。
それは古文です。
いや、古Perlです。
もしあなたがuse strict無しの「古Perl」を身に着けてしまうと、後で必ずuse strict有りの「今Perl」を勉強しなおすハメになります。
これはものすごい時間の無駄です。
だから、Perlを勉強し始めたら、絶対書きましょう。
幸せの呪文です。
さあ、ご一緒に
use strict !!
use strict !!
use strict !!
いや、正しくはこう。
Perlの世界へようこそ。
use strict ワールドへようこそ。
Perl/CGI初心者へ。 use strictは絶対に書きましょう!!
書き方#!/usr/bin/perl
use strict;
または
#!/usr/local/bin/perl
use strict;
解説はこちら: Perl/CGIに必ず登場するuse strictの解説(初心者向け) Perl/CGI初心者へのアドバイス。
よい子のお約束です。- use strictと書かずに、Perlプログラムを書いてはいけません。
- use strictと冒頭に書かれていないPerlのソースコードをマネしてはいけません。
- use strictと書かれていないPerl/CGIの参考書は参考にしてはいけません。
use strcitを知らないと損をします。
use strict無しのPerl、それは古文です。
いや、古Perlです。
もしあなたがuse strict無しの「古Perl」を身に着けてしまうと、後で必ずuse strict有りの「今Perl」を勉強しなおすハメになります。
これはものすごい時間の無駄です。
だから、Perlを勉強し始めたら、絶対書きましょう。
幸せの呪文です。
さあ、ご一緒に
use strict !!
use strict !!
use strict !!
いや、正しくはこう。
#!/usr/bin/perl
use strict;
または
#!/usr/local/bin/perl
use strict;
c:\> perl -e "print chr(7)"
WindowsにActivePerlがインストールされている場合、上記コマンドを打つとPCからビープ音が鳴ります。
マシンによっては大きい音が出るので、周囲にご注意を。
こちらの記事に触発されて、Perlでできないかやってみたら簡単にできました。
Beep音を鳴らす@VBScript
文字コード7番はBeep音ということで、プログラム言語を問わず共通なのでしょうか。
なお、コマンドプロンプトではCtr + G + EnterでもBeep音を出せるそうですね。
知らんかった。
ある特定のモジュールが、自分のマシンにインストール済みかどうかを調べる方法。
例えば、File::Pathモジュールが入っているかどうかを調べたいなら
c:\>perl -MFile::Path -e;これでエラーが出なければ、入っている。
逆に、入っていないモジュールの場合だと、
c:\>perl -MFoo::Bar -e;
Can't locate Foo/Bar.pm in @INC (@INC contains: ....みたいなエラーが出る。
Googleでいろいろ検索したんですが、@INCの中身を調べて..みたいな大掛かりなやり方しか出てきませんね。
結局、自分で上記方法を思いつきました。
何か間違ってたら、ご指摘くださいませ。