feb19.jp

Nobuhiro Takahashi
Designer / Engineer

Perl 勉強メモ

date
2013.5.13(Mon.)
tags
PerlTips

Perl を勉強したりしたメモを残しておきました。

文字列を扱う

string.pl として保存して、macOS であれば Terminal から perl string.pl で実行できます。

use strict;
use warnings;
 
# 結合
my $join1 = 'aaa'.'bbb';
print "$join1\n";
 
# 結合(別の方法)
my $join2 = join(',', 'aaa', 'bbb', 'ccc');
print "$join2\n";
 
# 分割(,で分割)
my @record = split(/,/, 'aaa,bbb,ccc');
print "@record\n";
 
# 文字列の長さ
my $length = length('abcdef');
print "$length\n";
 
# 切り出し
my $substr = substr('abcd', 0, 2);
print "$substr\n";
 
# 検索(値が存在する位置番号を取得。見つからなかった場合は -1)
my $result = index('abcd', 'cd');
print "$result\n";
% perl string.pl 
aaabbb
aaa,bbb,ccc
aaa bbb ccc
6
ab
2

モジュール化(クラス化)してオブジェクト指向プログラミング

クラス(モジュール)を作成し、サブクラスをさらに作成するサンプルです。モジュールの拡張子は .pm です。

Point.pm

package Point;
 
use strict;
use warnings;
 
# コンストラクタは便宜的に new という名前
# my $point = Point->new(x=>2, y=>3);
sub new {
    my $class = shift();
    my $self = {
        x => 0,
        y => 0,
        @_
    };
    return bless($self, $class);
}
 
# $point->x とすれば x の値が取れる
# $point->x(0) とすれば x の値を 0 にできる
sub x {
    my $self = shift();
    if (@_) {
        $self->{x} = $_[0];
    } else {
        return $self->{x};
    }
}
 
# $point->y とすれば y の値が取れる
# $point->y(0) とすれば y の値を 0 にできる
sub y {
    my $self = shift();
    if (@_) {
        $self->{y} = $_[0];
    } else {
        return $self->{y};
    }
}
 
# 値をクリアして 0 にする
# $point->clear();
sub clear {
    my $self = shift();
    $self->x(0);
    $self->y(0);
}
 
# モジュールは最後にこれを付ける
1;

Point3D.pm

package Point3D;
 
# 継承
use base "Point";
 
# コンストラクタは便宜的に new という名前
# my $point3 = Point3D->new(x=>2, y=>3, z=>4);
sub new {
    my $self = shift()->SUPER::new(@_);
    $self->z = 0 unless exists $self->{z};
    return $self;
}
 
# $point3->z とすれば z の値が取れる
# $point3->z(0) とすれば z の値を 0 にできる
sub z {
    my $self = shift();
    if (@_) {
        $self->{z} = $_[0];
    } else {
        return $self->{z};
    }
}
 
# 値をクリアして 0 にする
# $point3->clear();
sub clear {
    my $self = shift();
    $self->SUPER::clear;
    $self->z(0);
}
 
# モジュールは最後にこれを付ける
1;

point.pl

use strict;
use warnings;
 
use Point;
use Point3D;
 
# Point
my $point = Point->new(x=>2, y=>3);
print("[".$point->x.",".$point->y."]\n");
$point->clear();
print("[".$point->x.",".$point->y."]\n");
$point->y(4);
print("[".$point->x.",".$point->y."]\n");
 
# Point3D
my $point3 = Point3D->new(x=>2, y=>3, z=> 4);
print("[".$point3->x.",".$point3->y.",".$point3->z."]\n");
$point3->clear();
print("[".$point3->x.",".$point3->y.",".$point3->z."]\n");

出力

% perl point.pl 
[2,3]
[0,0]
[0,4]
[2,3,4]
[0,0,0]

Amon2 で DB を利用したウェブアプリを作る

セットアップ

とりあえず Large フレーバーで作ってみます。

$ amon2-setup.pl HelloWorld --flavor Large
$ cd HelloWorld
$ carton install
$ sqlite3 db/development.db < sql/sqlite.sql

デフォルトで sql/sqlite.sqllib/HelloWorld/DB/Schema.pmmember テーブル (id, name) を持つ DB と O/R マッパーができるので、これにデータを足していくアプリにしてみる。

Perl: lib/HelloWorld/Web/C/Root.pm

package HelloWorld::Web::C::Root;
use strict;
use warnings;
use utf8;
 
sub index {
    my ($class, $c) = @_;
    
    my $counter = $c->session->get('counter') || 0;
    $counter++;
    $c->session->set('counter' => $counter);
    my @members = $c->db->search_by_sql(q{
        SELECT * FROM member ORDER BY id DESC LIMIT 10
    });
    return $c->render('index.tx', {
        counter => $counter,
        members => \@members,
    });
}
 
sub post {
    my ($class, $c) = @_;
    
    if ( my $body = $c->req->param('body') ) {
        $c->db->insert(
            'member',
            +{
                name => $body,
            }
        );
    }
    return $c->redirect('/');
}
 
sub reset_counter {
    my ($class, $c) = @_;
 
    $c->session->remove('counter');
    return $c->redirect('/');
}
 
1;

Perl: lib/HelloWorld/Web/Dispatcher.pm

post '/post' => 'Root#post';

一行追加

Kolon: tmpl/web/index.tx

上の方に追加 Amon2 のテンプレートデフォルト文法いつの間にか TTerse から Kolon になってたので Kolon で記述

<form method="post" action="<: uri_for('/post') :>">
  <input type="text" name="body" />
  <input type="submit" value="Send" />
</form>
 
<table>
: for $members -> $member {
  <tr>
    <td><: $member.id :></td>
    <td><: $member.name :></td>
  </tr>
: }
</table>

起動

$ carton exec perl -Ilib script/helloworld-web-server

http://127.0.0.1:5000 をブラウザで開くとフォームが出来ていて、Send したらデータが追加されていけば完成。