ブログトップ 記事一覧 ログイン 無料ブログ開設

サンプルコードによるPerl入門 - 未経験からプロの技術が身につくPerl講座

★★ 未経験から初めて、プロの実力がどんどん身につく、Perl入門講座 ★★
テキスト処理ならPerlが最適。if文,for文,配列,ハッシュ,正規表現を覚えれば、ログ解析も自由自在。大量のExcelデータを高速に集計。Webサイトを作成して、独自のサービスの展開も! 関数とモジュールを覚えれば業務効率が劇的に改善。初級から上級まで、Perlのすべてが学べます。「へぇー、こうすればこんなに簡単にできるんだ!!」プログラミングの面白さを実感しよう。
プロとして第一線で活躍し続けるために、プログラミングの確かな実力を「サンプルコードによるPerl入門」で身に着けてみませんか

2009-11-20

現代的なPerlの記述方法一覧

 Perl5.8以降における標準的なPerlの書き方を解説します。インターネットで検索するとPerl4のころの古い記述がたくさんあります。また書籍などの多くもPerl4の記法で書かれています。Perl4の記法は複雑になりやすく間違いを生みやすいのでこれからPerlを書く人はPerl5の現代的な記法で記述することを強くお勧めします。

strictプラグマとwarningsプラグマ (必須)

 strictプラグマとwarningsプラグマを有効にします。

use strict;
use warnings;

 use strict;とuse warnings;の2行はスクリプトの最初に必ず記述してください。これらはPerlの文法チェックを厳しくするためのものです。面倒だという軽い気持ちでこれを記述しないと後々本当に面倒なことになります。

 use strict;とuse warningsを書かなくてもよいのはワンライナーと呼ばれるコマンドラインスクリプトを記述するときだけだという風に考えてください。

ファイルハンドルにはレキシカル変数を使うこと (本当に特別な用途がない限りは必須)

 ファイルハンドルには宣言したばかりのレキシカル変数を使います。レキシカル変数を宣言してそれをopen関数の第1引数に指定するとレキシカル変数にファイルハンドルが設定されます。

# レキシカル変数
my $fh;
my $file = 'file1';

open $fh, '<', $file
  or die "Cannot open '$file': $!";

while (my $lien = <$fh>) {
  ...
}

 レキシカル変数はスコープを持つということと他の関数に引数として渡すことができるという大きな利点があります。古い解説にあるようなFHや*FHなどのシンボルを使わないようにします。

 またレキシカル変数の宣言をopen関数の中にまとめてしまうのがより現代的であるといえるでしょう。

open my $fh, '<', $file

3引数のopen関数を使う (必須)

 3引数のopen関数を使用するようにします。

open my $fh, '<', $file

 古い解説では2引数のopen関数を解説しているものがありますが使わないようにしましょう。2引数のopen関数はセキュリティ的に脆いので使用してはいけません。

open my $fh, "< $file"; # 2引数のopen関数を使用してはいけない

 これはパイプをオープンするときにも当てはまります。

# ○ (三引数)
open my $pipe, '-|', 'dir';

# × (二引数)
open my $pipe, 'dir |';

ファイルオープン時のエラー処理を行う (必須)

 ファイルオープンを行ったときは必ずエラー処理を行うようにします。

open my $fh, '<', $file
  or die "Cannot open '$file': $!";

 open関数は失敗するとundefを返すのでorを使ってエラー処理を行います。$!にはOSが返したエラーメッセージが含まれているのでユーザに見せるエラーメッセージに含めるようにします。

 プログラムをエラーメッセージを表示して終了させるにはdie関数を使用します。他のプログラムから見た場合は終了コードは255になります。

 ファイルオープンに限らずプログラムの外部と通信する場合はかならずエラー処理を行うようにします。外部というのはメモリの操作を除くすべてです。ファイルやネットワークなどが外部になります。

レキシカル変数とサブルーチンの名前には小文字とアンダーバーを使用する (強く推奨)

 「myで宣言されるレキシカル変数」と「サブルーチン」の名前には小文字とアンダーバーを使用します。

# レキシカル変数
my $user_name;
my $search_word;
my $max_database_connection;

# サブルーチン
sub parse_data {
  ...
}

sub create_table {
  ...
}

 この記法が良いか悪いかは別にしてCPANにある新しいモジュールのほとんどはこの記法で書かれています。この習慣にしたがっておいたほうがユーザに統一されたインターフェイスを提供できるという点で非常に多くの益があります。

 変数の命名方法には別に記事を書いていますのでこちらも参考にしてください。

<変数に適切な名前をつける>

 サブルーチンの命名方法は原則として「動詞 + 名詞」です。意味がはっきりとわかるものについてはユーザの利便性を考えて「動詞」だけにしても良いかもしれません。ただし後で困ることがあるので「動詞 + 名詞」にしておくのが無難だと思います。

パッケージ変数には大文字とアンダーバーを使用する (強く推奨)

 パッケージ変数には大文字とアンダーバーを使用します。

our $OBJECT_COUNT;
our $CLASS_INFO;

パッケージ変数は使わずにレキシカル変数を使うようにする (必須)

 もしあなたがモジュールの作者でないのであればパッケージ変数を使う機会はありません。もし単体のスクリプトの中でパッケージ変数を使っているとしたらそれは間違った使い方です。myを使ったレキシカル変数に変更しましょう。

標準的(?)なコードのフォーマットで書く (少し推奨)

 コードの書き方には好き嫌いがあるのですが、Perlベストプラクティスで紹介されている書き方やPerltidyと呼ばれるコード整形ツールが出力する形式にあわせておいたほうが幾分よいと思います。

 サンプルとしてMojo::URLのソースコードのリンクを張っておきます。これをまねして書けば覚えられます。

 <Mojo::URLのソースコード>

 まねするポイントを少しだけ書いておきます。

1. ifやforeach文やサブルーチンなどのスペースの入る位置を見る
# ifの直後にスペースがあって、()の中にはスペースがないなど
if ($flg) { 
  ...
}
2. コメントの書き方やスペースの入れ方などを見る

 コメントの書き方や行のスペースの入れ方などをみましょう。CPANに存在するほとんどのモジュールには親切なコメントがないのですが、個人的は簡潔なコメントをソースコードに書いてくれるとありがたいと思っています。

3. タブは使わないでインデントの幅はスペースで4(あるいは2)

 一応これはPerlベストプラクティスでいわれていることです。(最近の僕はスペース2です)。またタブを使いたいという人も中にはいると思いますので、これは個人の好みで。

日本語などのマルチバイト文字を適切に扱うためにEncodeモジュールを使用する (強く推奨)

 日本語などのマルチバイト文字を適切に扱うにはEncodeモジュールを使用します。こちらは記事にしましたのでリンクを張っておきます。

 <Encode 日本語などのマルチバイト文字列を適切に処理する>

 古い解説にあるようなJcode.pmやJcode.plを使うような手法は現在では推奨できません。Perl5.8以降はEncodeモジュールを使用するのが標準的で問題が少ない方法です。

デフォルト変数 $_ は使用しない (強く推奨)

 Perlにはデフォルト変数 $_ というものが存在します。デフォルト変数は関数に引数を指定しなかった場合に暗黙的に受け取る変数です。プログラムの中で使用すると可読性が落ちるので使うのは控えましょう。

 デフォルト引数を使用するのは次の場合だけです。

1. ワンライナー

 ワンライナーの中では使用してもよいと思います。printの引数や正規表現の対象として$_が利用されています。

# AAAという文字を含む行を取り出すワンライナー
perl -ne "print if /AAA/";
2. map関数とgrep関数と後置のfor

 map関数やgrep関数や後置のforには$_ がわたってきますのでこれは利用せざるをえないです。

my @greped_array = grep { $_ =~ /AAA/ } @array;
my @mapped_array = map  { $_ * 2 } @array;
print $_ for @array;

 有名なCPANモジュールの中にはデフォルト変数を使用しているものがありますが個人的には推奨しません。できるだけ明示的であったほうが可読性の高いプログラムになります。

foreach文ではレキシカル変数を宣言する (強く推奨)

 Perl5ではforeach文の先頭でレキシカル変数を宣言することができます。

my @students = ('taro', 'kenji', 'naoya');
for my $student (@students) {
  ...
}

 この例の場合は@studentsの各要素が$studentに入ってきます。$studentはレキシカル変数でforeachのブロックの先頭から終わりまでのスコープを持ちます。

 レキシカル変数を省略するような書き方もできますが推奨しません。

# 推奨できない書き方
for (@students) {
  ...
}

コマンドライン引数の受け取りかた (参考)

 コマンドライン引数はこんな感じで受け取るのがよいです。

# コマンドライン引数がひとつの場合
my $file = shift;
# コマンドライン引数が複数の場合
my ($file, $option) = @ARGV;

サブルーチンの引数の受け取り方 (参考)

 コマンドライン引数の場合と同様になります。

# 引数がひとつの場合
sub func {
  my $file = shift;
}
# 引数が複数の場合
sub func {
  my ($file, $option) = @_;
}

日付処理の標準モジュールを使用する (参考)

 もしPerl5.10以降を使用しているならTime::Pieceというモジュールが標準で添付されており日付処理に使えます。

 <Time::Piece - 日付・時刻を扱うための標準モジュール>

 またCPANからインストールできる環境であればDataTimeモジュールをインストールするのも良いかもしれません。こちらは高機能ですが少し重いです。

 <日付を汎用的に扱うモジュール DateTime>

 それもできないならlocaltimeやTime::Localでがんばります。

 <Perlでの日付・時刻の扱い>

不必要なモジュールの読み込みは行わないこと (必須)

 他のプログラムのソースコードをコピーしてきた場合にそのプログラムでは使用しないのに余計なモジュールが読み込まれている場合があります。これは後で読んだ人に対していらぬ誤解を招くので必ず削除するように心がけましょう。

# 他のプログラムからソースコードをコピーしてきたために
# 不必要なモジュールの読み込みが残る場合があるので
# 気をつける
use File::Spec;
use File::Basename 'basename'; 
                               

Perlのドキュメントの書き方 (参考)

 仕事で使用する小さなスクリプトの場合はスクリプトの中にドキュメントを埋め込んでおくのがよいと思います。CPANモジュールの場合はソースコードの末尾がドキュメントになりますが、小さなスクリプトの場合は先頭に書いておくと利用者がソースコードを開いたときにぱっとみることができるので便利です。

 PerlのドキュメントはPODと呼ばれる記法で書きます。簡単な書き方だけ紹介しておきます。「=head1」というのが見出しになります。「=head1」の右にタイトルを書きます。その下に一行あけて本文を書きます。一行あけるというのには意味があるので注意してください。ドキュメントの終わりは「=cut」という行になります。英語で書いた場合は次のようになります。

=head1 SCRIPT NAME

SomeScript.pl

=head1 DESCRIPTION

This script is used to do ....

=head1 USAGE

perl SomeScript.pl file1 file2 ...

=cut

# ソースコードの始まり
use strict;
use warnings;

 ローカルなプロジェクトの場合は同僚にわかりやすく伝えるために日本語で書くのがよいと思います。

=head1 スクリプト名

SomeScript.pl

=head1 概要

〜するためのものです。

=head1 使用方法

perl SomeScript.pl file1 file2 ...

=cut

# ソースコードの始まり
use strict;
use warnings;

コメントの#の嵐は避ける (推奨)

 よく#だらけのコメントを仕事をしててみるのですが個人的にはお勧めしません。一番の理由は一度そのコメントの記述を行うと後から来た人がそれをまねしないといけないからです。関数ひとつ記述するのにこれをまねしないといけないのかと思うと気持ちが萎えます。またコードの品質を上げるどころか関数を書き換えたときにコメントが追いついていないということが頻繁に起きます。ですのでやめましょう。

#################################################################
# 関数名     : ほにゃらら                                       #
# 引数       : 引数1 引数2                                      #
# 戻り値     : ほにゃらら                                       #
# 作成日時   : あああああ                                       #
# 作成者     : ほれほれ                                         #
# 関数の説明 : いいいいいい                                     #
# 更新履歴   : その1                                            #
#            : その2                                            #
#            : その3                                            #
#################################################################
sub func {
    
}

 こちらの書き方をお勧めします。

# 簡単な解説(1行で)
sub func{
    
}

 <Mojo::URLのソースコード>

も参考にしてください。

文字列リスト演算子 (参考)

 文字列リスト演算子はよく使用されるので解説しておきます。文字列リスト演算子は文字列の配列を作成するのによく利用されれます。

my @strings = qw/aa bb cc/;

 次の記述と同じ意味があります。

my @strings = ('aa', 'bb', 'cc');

モジュールの関数をインポートするときは明示する (強く推奨)

 モジュールで関数をインポートするときは明示するようにしたほうがよいでしょう。ソースコードを読んだ人がその関数はどのモジュールのものなのかを簡単に理解することができます。

use File::Basename 'basename';
use File::Copy qw/copy move/;
use File::Path 'mkpath';
use Encode qw/encode decode/;

# mkpath関数を使用する。
mkpath $dir;

 もし明示的なインポートの記述がなかった場合はどうなるでしょう。

use File::Basename;
use File::Copy;
use File::Path;
use Encode;

# これはどこからインポートされたかわからない 
mkpath $dir; 

 このような場合はuseされているすべてのモジュールのドキュメントを読むということになりかねません。あなたは関数がどのモジュールからインポートされたのかを知っているかもしれませんが、ソースコードを読む人には明示的ではありません。ですのでインポートする関数はどんなにあなたにとって明らかに思えても明示的に指定するようにしましょう。

gotoは使用しない (本当に特別な場合を除いて必須)

 Perlにはgoto文がありますが使用してはいけません。gotoを使うプログラミングはPerlに限らずもう過去のものです。もしあなたが何らかの理由でgotoを使いたくなった場合代替する手段は必ず用意されていると思ってください。

 ループ制御を行いたいなら「last」「next」を使用してください。エラー処理を行いたいならdieを使って例外を投げてください。

 (gotoを使用しなければならない場面は、無限再帰呼び出しなどで、関数の階層を深くしたくないなどという本当に特殊な場合だけです。)

do 〜 whileは使用しない (推奨)

 do whileで記述できる文はwhileで必ず記述できます。do whileを使ったからといって記述が簡潔になるかといえばそうでもないです。逆に普段使用していない分だけ意図がわかりにくくなると感じます。

 do whileで記述できる文はwhileで必ず記述できるのでwhileを使うロジックを考えることをお勧めします。

redoは使用しない (推奨)

 Perlにはredo文がありますが、redoを使わなくても同じロジックを記述することができます。redoは何回か使用したことがあるのですが、redoを使ったプログラミングはとてもわかりにくくなると感じます。redoを使用しなくても同じロジックは必ず記述できるのでredoを使わないロジックを考えることをお勧めします。

プロトタイプは使用しない (強く推奨)

 サブルーチンを定義するときにプロトタイプという型を指定できる機能がありますがこれは使用しません。

# プロトタイプは使用しないこと
sub func ($@) {
  ...
}

 Perlでは明示的に型を指定しなくてもどのような型の引数も受け取れますし、引数の個数もいくつでもかまいません。ですのでプロトタイプで型を指定したり個数を指定したりする必要はまったくないのです。ですので必ずプロトタイプを指定しないサブルーチンの定義を行いましょう。

sub func {
  ...    
}

エラーを伝えるときはundefを戻り値として返却するのではなくdieを使用する。(推奨)

 Perlには例外処理がないと思っている人もいるかもしれません。Javaのような例外オブジェクトというものはありませんが、簡潔な例外機構を備えています。

 まずは旧来のエラー処理であった戻り値にundefを返却する方法を見ます。エラーが発生したときに単独のreturnを記述するとスカラコンテキストの場合はundefがリストコンテキストの場合は空のリスト () が返却されます。

# エラーが発生したときにundefを返却する
sub func {
  my $arg = shift;
  
  ...
  
  # エラー処理
  if ($error) {
    return; 
  }
  # エラーが起こらなかった場合の正しい値
  return $val;
}

 そして関数を呼び出す側でエラー処理を記述します。

my $val = func();

# $valが偽値だったらプログラムを終了
die "Error" unless $val;

 この記述の問題点はfuncを使う人が戻り値のチェックを怠るとプログラムは先に進んでしまうということです。

 ですので現在的なPerlではエラーを伝えるときにdieを使って例外を投げます。

# エラーが発生したときにdieを使って例外を投げる
sub func {
  my $arg = shift;
  
  # なんらかの処理
  
  # dieを使って例外を投げる
  if ($error) {
    die "Error message";
  }

  # エラーが起こらなかった場合の正しい値
  return $val;
}

 このようにするとfuncを呼び出してエラーが発生したときはエラーメッセージを表示してプログラムは終了します。

# エラーが発生した場合はエラーメッセージを表示してプログラムが終了
func(); 

 プログラムを終了させたくない場合はeval { }; で受けます。これはJavaでいうcatchだと思ってください。エラーが発生した場合は$@という特殊変数にエラーの内容が設定されますので、この変数をチェックすることでエラーが発生したかどうかを調べることができます。

eval { func() };

if ($@) {
  # エラーが発生した場合の処理を記述
}

コンストラクタの呼び出しではアロー演算子を利用する

 コンストラクタの呼び出しはアロー演算子を使用するのがよいでしょう。Perlではコンストラクタと他のメソッドに実質的な違いはありません。

my $obj = SomeClass->new;

 間接オブジェクト呼び出しは、将来的には非推奨になる可能性があります。

# 間接オブジェクト呼び出し
my $obj = new SomeClass();


目次

通りすがり通りすがり 2009/11/01 23:31 (一応タグ -> タブ)
プロトタイプを使わない理由を教えてもらえませんか?

tokuhiromtokuhirom 2009/11/02 00:03 open の引数をチェックするのはいいのですが、より楽な方法として autodie.pm も最近の perl だとつかえます :)
(対象読者的に言及する必要はないとおもいますが、念のため)

laclefdorlaclefdor 2009/11/02 09:16 これは素晴らしいエントリー。ありがとうございます。

yappoyappo 2009/11/02 14:53 sub foo (&@) {} の件に言及してあると良かったかと思います。(AUTOLOAD の goto に言及してあるので)

otsuneotsune 2009/11/02 18:53 「タグは使わないでインデントの幅はスペースで4」
はindentの文脈だとすると「Tab or space」のことだと思われるので
s/タグ/タブ/

perlcodesampleperlcodesample 2009/11/02 20:01 「タグ」→「タブ」に修正しました。

canadiecanadie 2009/11/03 15:57 まず「インポートせずに明示する」を推奨してはいかがでしょう?

use Data::Dumper;
use YAML::Syck;

print Dump($foo); # えーと、どっち?

print YAML::Syck::Dump($foo); いちいち行を遡る必要がない。

perlcodesampleperlcodesample 2009/11/03 18:18  一番重要な点はプログラムを読んだときにどのモジュールからインポートされたかがわかるかどうかという点だと思っています。ですので明示的にインポートを記載する方法も、canadieさんのいうように完全修飾名で関数を呼ぶようにする方法もどちらもグッドプラクティスだと思います。
 自分がコードをたくさん書いていて感じることは、ソースコードを読む前に先頭のインポートの記述に目を通しておけば、完全修飾しなくてもわかりにくくなることはほとんどないということです。
 関数名がぶつかるときだけは完全修飾が必要になる感じです。

PBPPBP 2009/11/04 17:03 Keep list assignment consistency.
(LIST) = (LIST)
Even if there is one argument, you can do

sub func {
my ($file) = @_;
}

like multiple arguments case.

sub func {
my ($file, $option) = @_;
}

instead of

sub func {
my $file = shift;
}

Read
http://mail.pm.org/pipermail/edinburgh-pm/2007-September/000478.html

konbuizmkonbuizm 2009/11/05 07:02 うーん、たしかにプロトタイプは不要かもしれないけど、便利な面もありますよ。
実行前にコンパイルエラーで失敗するケースがあるので、サブルーチン利用者にサブルーチン開発者の意図が伝わる点は好きです。

$ cat func.pl
sub func($;$) { 1 }
func('a'); # ok
func('b','c'); # ok
func('b','c','d'); # bad
$ perl -cw func.pl
Too many arguments for main::func at func.pl line 4, near "'d')"
func.pl had compilation errors.
$

末尾に補足があるけどまだ理由が弱い気がします。
プロトタイプのデメリット一覧、メリット一覧があると、強く非推奨の理由が納得してもらえるかも。

fkdfkd 2010/02/14 10:38 こんにちは
インデントについてですが、タブでなくスペースというのは共感できます。
インデント幅が(2でもなく3でもなく)4なのは何か理由がありますか?

shin_1985shin_1985 2010/02/16 01:31 ファイルオープンの書き方は初めて見ました。
(人のコードを普段読むことがないもので・・・)
参考にさせてもらいます。

perlcodesampleperlcodesample 2010/02/17 22:51 > fkd
 インデント幅4についてですが、これは「Perl グッドプラクティス」という本に載っているもので、Perlでソースコードを書く多くの人が参考にしています。また最近のPerlのソースコードを見てもインデント幅4が主流になっています。
 インデント幅についてはわたし的には2でも4でも8でもいいのですが、Perlの標準的な作法に合わせておくことが無難な書き方だと思いますし、余計な考え事をしないですむのではないかと思っています。

fkdfkd 2010/02/20 19:32 わかりました。ありがとうございます。

tttttt 2010/04/24 02:13 インデントはTabの方が楽で早くて揃えやすいのでこのんで使うのですが、スペースを使いたがる理由が理解できないのですけども、分かりやすくご解説願えませんでしょうか

perlcodesampleperlcodesample 2010/04/24 20:55 tttさん
 インデントとスペースが混ざってしまうと、タブ幅が異なるエディタで見たときに見た目が変わってしまうというのがひとつの理由です。コードはみんなで使うので見た目が統一しておくのがよいとされています。
 現在のエディタはTabキーで4文字のスペースを入力する設定がついているものが多いのでそれほど苦労することはないと思います。

 (でもある意味ではこれは「Perlグッドプラクティス」で紹介されている方法なので、歩調を合わせるためにほとんどの新しいモジュールが採用しているというのがあるかもしれません。またこれが標準的な書き方なんですということを説明すれば、チーム内でのスタイルに対する合意がとりやすくなります。)

奈良阪奈良阪 2012/04/22 16:00 タブ派ですねえ。expandtabしてくれるエディタじゃなくてもタイプ数が少ないし。

あと些細ですがeval { }; はJavaでいうcatchじゃなくてtryだと思います。
catchはif($@)のほうかと。
Javaはむかしちょろっと使っただけですけど、たぶん……。

通りすがり通りすがり 2012/11/28 23:23 プロトタイプのメリットは、以下のような組み込み関数をユーザでも使いたい場合ですね。
たとえば、chr 関数は chr NUMBER で引数は1つの定義になってます。

printf "%s %s %s\n", chr(97), 98, 99; # chrには97が引数となる
printf "%s %s %s\n", chr 97, 98, 99; # chrは引数を1つなので、()がなくても同じ意味
# printf "%s %s %s\n", chr(97, 98, 99); # 引数が定義と異なるのでコンパイルエラー

sub chr_u1 { return chr shift }
sub chr_u2($) { return chr shift }

printf "%s %s %s\n", chr_u1 97, 98, 99; # (97,98,99)の配列を引数と解釈してしまう。
printf "%s %s %s\n", chr_u2 97, 98, 99; # プロトタイプで引数が1つなので 97のみを引数とみなす。

プロトタイプの仕組みがないと、こういったユーザー定義関数が作成できません。
例えば、引数を2つに固定した関数なら、緯度経度を与えて国別コードを返す関数とか、
虚数を扱うような関数、、とか、ケースによってさまざま。
曖昧さを解決するには()で明示すればいいじゃん、というのも考え方ですが、
プロトタイプの導入は、組み込み関数と同じようにユーザ定義関数も定義できるべき、っていう考えからスタートしてます。
perlではカッコをあまり書かないで済むように工夫されていますが、
そうしたいのに、そうできる手段がない、というのは設計哲学的に矛盾なのですね。

通りすがり通りすがり 2012/11/28 23:50 インデントは共同作業するときに、必ず揉める種のひとつですね^^;
個人的には、マクロやコマンドでインデントを一発整形*できない*エディタを使用する方が悪い!
とすら思ってますw
インデントの作法を統一するためにチームで使うエディタを統一しよう、という話にはならないから不思議w
subversionやgitで co したファイルはエディタでインデント整形してから読めばいいんですよ。
むしろ1つのファイルを複数人で編集せざるを得ない開発状況こそ改善すべきだと思います。

# それでも統一したいのなら、納品前にソース整形ツールにかければいい話。

ももちももち 2013/05/29 09:23 自分は公開用と非公開用とでスタイルを分けています。公開用はもちろんここに書かれた方法に似ています。非公開用はタブで、予約語の前後に余分な空白を入れません。

perlcodesampleperlcodesample 2013/05/29 13:49 ももちさん
 はい、それでいいと思います。

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証