目の前に僕らの道がある

勉強会とか、技術的にはまったことのメモ

Mooseを使ってみた

Perlでもクラスを書きたいよねってことでMooseを調べてみました。

オブジェクト指向の例題にある犬クラスとか猫クラスみたいなのじゃつまらないので、一昨日書いたEmail::SendのラッパークラスをMooseを使って書いてみました。

Perldocっぽいものも一応書いています。

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;

package MailSender;
use Moose;

# プロパティ
has 'from' => (
    is       => 'ro',  # 読み取り専用
    isa      => 'Str', # Str型のみ代入可
    required => 1,     # オブジェクト生成時に必ず必要
);

has 'to' => (
    is       => 'ro',
    isa      => 'Str',
    required => 1,
);

has 'subject' => (
    is       => 'ro',
    isa      => 'Str',
    required => 1,
);

has 'body' => (
    is       => 'ro',
    isa      => 'Str',
    required => 1,
);

has 'server' => (
    is       => 'ro',
    isa      => 'Str',
    required => 1,
);

has 'mail' => (
    is      => 'rw', # 読み書き可
);

__PACKAGE__->meta->make_immutable;
no Moose;

use Encode;
use Email::MIME;
use Email::MIME::Creator;
use Email::Send;

# コンストラクタ
sub BUILD {
    my $self = shift;

    $self->mail(
        Email::MIME->create(
            header => [
                From    => $self->from,
                To      => $self->to,
                Subject => Encode::encode('MIME-Header-ISO_2022_JP', $self->subject),
            ],
            parts => [
                encode('iso-2022-jp', $self->body),
            ],
        )
    );

    return $self;
}

# メール送信メソッド
sub mail_send {
    my $self = shift;

    # メールを送信する
    my $sender = Email::Send->new({mailer => 'SMTP'});
    $sender->mailer_args([Host => $self->server]);
    $sender->send($self->mail);
}

1;

__END__

=head1 NAME

MailSender - A class which sends a mail.
MailSender - メールを送信するクラス

=head1 SYNOPSIS

    use MailSender;
    # generate MailSender object.
    # オブジェクトの生成
    my $sender = MailSender->new(
        from    => '送信元アドレス',
        to      => '宛先アドレス',
        subject => 'タイトル',
        body    => 'メール本文',
        server  => 'メールサーバ',
    );
    # send a mail
    # メール送信
    $sender->mail_send();

=head1 DESCRIPTION

MailSender offers the feature sending a email. It is implemented as wrapper class of Email::Send.
MailSenderはメール送信する機能を提供します。 Email::Sendのラッパーとして実装されています。

BUILDメソッドはコンストラクタです。isでアクセス権限、isaで型が指定できるのがすばらしいです。

Perldocにも書いてありますが使い方はこんな感じです。

#!/usr/bin/env perl
use MailSender;
use strict;
use warnings;
use utf8;

# オブジェクトの生成
my $sender = MailSender->new(
    from    => '送信元アドレス',
    to      => '宛先アドレス',
    subject => 'タイトル',
    body    => 'メール本文',
    server  => 'メールサーバ',
);
# メール送信
$sender->mail_send();

Perl初心者なのでいまいち分からないのですが、こんな書き方でいいのでしょうか。

ちなみに後から気がついたのですが、コンストラクタではなくbuilderでEmail::MIMEを生成した方がいいような気がします。

has 'mail' => (
    is      => 'ro',
    lazy    => 1,             # 最初に呼ばれた時に初期化
    builder => 'build_mail',  # 初期化メソッド
);
# snip...
sub build_mail {
    my $self = shift;
    Email::MIME->create(
        header => [
            From    => $self->from,
            To      => $self->to,
            Subject => Encode::encode('MIME-Header-ISO_2022_JP', $self->subject),
        ],
        parts => [
            encode('iso-2022-jp', $self->body),
        ],
    );
}