Perl/CGIプログラムのパターンマッチ(3)
今回で、パターンマッチと正規表現はとりあえず終了です。
編集前記
今回の編集前記は、 Perl/CGIプログラム で日本語を使うとき注意すべきこと(その2)と題しまして、書いてみたいと思います。
今回も、この日本という国でPerl/CGIプログラムを作成していくための必須の知識を伝授します(笑)。
前回は同じテーマで、 文字化けの注意とその発生プロセス についてお伝えしましたね。
忘れちゃった場合は、ぜひ読み返してほしいところです。
今回は、「日本語文字に対しての各関数の扱いを注意する」ということについて、お話していきます。
前にも書きましたが、Perl/CGIプログラムに使用する各関数というのは、基本的に、半角英数や半角記号文字に対しての動作を前提に作られています。
ですので日本語のような全角文字を扱うときには、それとは別に、使用するであろう各日本語文字コードの性質や癖を、ある程度理解しておく必要があります。
例えば、文字のバイト数を返す length関数 があります。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print length("A");
exit;
実行結果は「1」です。
16進コード の内訳は「\x41」です。
「A」文字は、16進コード1つで表現可能な1バイト。
半角英数記号文字は、すべて1文字1バイトで計算することができるようになっています。
1文字1バイトですから、4文字あれば4バイト。
つまり、length関数を使ってバイト数を求めれば、そこから簡単に文字数を割り出すことができるというわけです。
もちろん日本語文字でも、length関数を使って文字数を計算することはできます。
しかし、同じ日本語文字でも採用する文字コードによって、バイト数が変わってくるのでそのあたりを理解して使う必要があります。
例えば、「あ」という文字に対する、各文字コードのlength関数の結果を見てみましょう。
まずは、Shift_jisコードから。
#!/usr/bin/perl
print "Content-type: text/html; charset=shift_jis\n\n";
print length("あ");
exit;
実行結果は「2」と表示されます。
16進コードの内訳は「\x82\xA0」です。
Shift_jisコードの「あ」は、16進コード2つで表現される2バイト。
続いて、EUCコードです。
#!/usr/bin/perl
print "Content-type: text/html; charset=euc-jp\n\n";
print length("あ");
exit;
実行結果は「2」と表示されます。
16進コードの内訳は「\xA4\xA2」です。
EUCコードの「あ」も、16進コード2つで表現される2バイト。
最後は、UTF-8コードです。
#!/usr/bin/perl
print "Content-type: text/html; charset=utf-8\n\n";
print length("あ");
exit;
実行結果は「3」と表示されます。
16進コードの内訳は「\xE3\x81\x82」です。
UTF-8コードの「あ」は、16進コード3つで表現される3バイト。
Shift_jisとEUCは2バイト、UTF-8は3バイト。
このように、採用する文字コードひとつでlength関数の結果も変わってくるわけです。
length関数の使用場面つまり、文字数を数える必要があるときというのはいろいろあるとは思いますが…
入力されたパスワードやお問い合わせ内容などの文字数に、制限をかけたいときや、電子メールのヘッダーを生成するときなどにも使います。
あと、携帯用のウェブサイトのHTTPヘッダー出力時にも使いますね。
趣味でPerl/CGIプログラムをしている場合は、バイト数や文字数を求める場面というのはそんなに多くありません。
しかし、いつかは必要なときが来る関数だと思うので、このような性質があることぐらいは、覚えておいたほうがいいでしょうね。
さらに、「日本語文字は1文字あたり複数のバイト数を持っている」ということを常に意識しておきましょう。
中には、Shift_jisコードの半角カタカナといった例外もありますが、それ以外の全角文字は、すべて2バイト以上が使われています。
したがって全角文字であれば、文字そのものを見て判断するのではなく、その中にある、複数のコードを見て判断するように意識しておくとよいでしょう。
例えばこれを見てください。
#!/usr/bin/perl
use strict;
print "Content-type: text/html; charset=shift_jis\n\n";
my $word = "こ";
my $search = "ア";
if (index ($word, $search) > -1) {
print "「$word」の中に「$search」が存在します。";
} else {
print "「$word」の中に「$search」は存在しません。";
}
exit;
実行結果はどうなると思いますか?
まぁこうしてわざわざ出すぐらいですから、おかしな結果になってしまうことは見え見えですが(笑)。
このPerl/CGIプログラムを実行すると…
「こ」の中に「ア」が存在します。
と表示されてしまいます。
if文 は成立してしまうのです。
index関数 の使い方についてはいいですよね。
説明済みですから、忘れてしまった場合は復習しておいてください。
Perl/CGIプログラム内で使われている文字だけ見れば、if文が成立するのはおかしいと思いますよね。
しかし、実際に使われている文字をいつものように16進コードに置き換えてみると、この動作の意味がわかります。
「こ」の16進コードは「\x82\xB1」です。
そして「ア」の16進コードは「\xB1」です。
「こ」の中に、「ア」を表す「\xB1」がみごとに入っていますよね。
だから、if文が成立してしまったというわけです。
一見、原因究明が難しそうなものでもこのように、16進コードにして考えてみると、簡単に原因が見えてくる場合があるので覚えておきましょう。
ここまで注意すべきことばかり書いてきました。
これだけ読むと、Perl/CGIプログラムで日本語を使うことに躊躇するかもしれません。
誰だって、めんどくさそうなことは嫌いですからね。
なので最後は、複数の16進コードで表すことができる日本語文字だからこそできるすこし面白いたとえを紹介しておきます。
#!/usr/bin/perl
use strict;
print "Content-type: text/html; charset=shift_jis\n\n";
my $word = "あ";
substr ($word, 1, 1, "\xA9");
print $word;
exit;
実行結果は「か」と表示されます。
「あ」とは表示されません。
「あ」を表している16進コードの一部を、 substr関数 を使って「か」に変更しました。
substr関数の使い方についてはわかりますよね。
忘れてしまった場合は復習しておいてくださいね。
「あ」を表している16進コードはおなじみの「\x82\xA0」です。
「か」を表している16進コードは「\x82\xA9」です。
もう、おわかりですね。
この中の「\x82」を残し、「\xA0」を「\xA9」に変更しました。
そうすると、「\x82\xA9」つまり、「か」になったというわけです。
少し面白いですよね。
実用的かどうかは疑問ですが(苦笑)。
まぁでもなんとなく、Perl/CGIプログラムで日本語を使っていく感覚がわかっていただけたのではないかと思います。
あとはあなた自身で、積極的に使っていって少しずつ慣れていってください。
一番効果的な学習法は、こうして知識を得た後に、自ら実践してみることですからね。
それに、自身の体験から振り帰ってみても、英語ばかりのものよりも、日本語を含んだものを作っているときのほうが、なんとなく楽しいような気がします。
さて、そろそろ今回の学習に移っていきましょう。
パターンマッチの変数
ここでは、 パターンマッチ に用いられる 変数 について見ていきましょう。
今まで学習してきました パターンマッチ に変数を加えて処理させることにより、もっと自由度の高いプログラムを作成することができるようになります。
パターンパート変数
パターンマッチが成立したとき、比較されている文字列というのは裏で自動的に大きく分けて3つのパートに分けられています。
1つ目は、マッチ部分。
2つ目は、マッチより前の部分。
3つ目は、マッチより後ろの部分。
これら3つの各パートは、自動的に特殊変数に格納されます。
各特殊変数は「$_」のように、その名前を指定することにより簡単に呼び出すことができます。
以下のPerl/CGIプログラム例を見てください。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$_ = "Perl/CGI";
/\//;
print $`, "<br>\n";
print $&, "<br>\n";
print $', "<br>\n";
exit;
このPerl/CGIプログラムを実行すると…。
Perl
/
CGI
と表示されます。
パターンマッチ部分は「/\//」です。
パターン文字は「\」直後にある「/」ですね。
比較する文字列は、いつものように「Perl/CGI」ですから「/」部分にマッチすることはわかりますよね。
このようなパターンマッチが成立するので前述しましたように、パターンマッチ部分と、その前後の値が自動的に特殊変数に格納されることになります。
動作結果からもわかるように、その後に各パートの特殊変数名を呼び出して出力させています。
つまり…。
「print $`, "<br>\n";」で、パターンマッチ部分よりも前を出力。
特殊変数名は「$`」。
「print $&, "<br>\n";」で、パターンマッチ部分を出力。
特殊変数名は「$&」。
「print $', "<br>\n";」で、パターンマッチ部分よりも後ろを出力。
特殊変数名は「$'」。
これらの特殊変数は覚えていないと使えませんが、無理して覚える必要はないです。
「パターンマッチでこんなこともできるんだな~」ぐらいに覚えておけばよいかと思います。
パターングループ変数
先ほどは、パターンマッチとその前後というものすごくざっくりしたわけ方をしました。
今度はパターンマッチの中で、もう少し細かく特殊変数への代入を指示する方法についてみていきましょう。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$_ = "Perl/CGI";
/(....)(.)(...)/;
print $1, "<br>\n";
print $2, "<br>\n";
print $3, "<br>\n";
exit;
このPerl/CGIプログラムを実行すると…。
Perl
/
CGI
と表示されます。
パターンマッチの中で「(」と「)」でパターン文字を囲むと、パターン文字をグループ化することができます。
グループ化されたパターン文字は、ひとつの塊として扱うことができます。
さらに、グループ化されたパターン文字は、パターンマッチの左から順番に特殊変数に代入されていきます。
特殊変数名は、代入された順番に「$1」「$2」「$3」…という感じに番号がついていきます。
以前に変数名のつけかたについて学習したことがありましたよね。
そのときに、スカラ変数を表す「$」の直後に数字が禁止されていたのはこのためです。
では、パターンマッチを見ていきましょう。
今回は「/(....)(.)(...)/」となっています。
「(」と「)」のペアが3つありますね。
このことから、3つにグループ化していることがわかります。
念のため、各グループを確認しておきましょう。
パターンマッチの左から順番に…。
1つ目のグループは「(....)」。
2つ目のグループは「(.)」。
3つ目のグループは「(...)」。
この3つにそれぞれ対応するのが「$1」「$2」「$3」なわけです。
そして「.」というのは、任意の1文字をあらわしています。
少し前にやりましたよね。
つまり…。
1つ目のグループは「(....)」なので、頭4文字を「$1」へ代入。
2つ目のグループは「(.)」なので、次の1文字を「$2」へ代入。
3つ目のグループは「(...)」なので、次の3文字を「$3」に代入。
比較される文字列は、いつものように「Perl/CGI」ですから…。
「$1」には「Perl」。
「$2」には「/」。
「$3」には「CGI」。
このように代入されるというわけです。
後は先ほどと同じように出力するだけですから簡単ですね。
ちなみに、今まで学習してきた知識を使うと、パターンマッチ部分というのはこのほかにも、いろいろな書き方ができます。
例えば、「.」が連続して使われるのが嫌ならば…。
「/(.{4})(.{1})(.{3})/」という感じに書き換えることもできます。
さらに、「.」を使わずに「[」と「]」でパターン文字候補をくくっても同じことができます。
このあたりは、前回の記事を読み返していただければわかることなので、あえて書きません。
パターンマッチはこのように、いろいろな書き方ができますから、あなたもぜひ試してみてください。
最大マッチと最小マッチ
前回、パターンマッチに出てくる「?」について、今回の学習で説明すると書きましたよね。
話がわからない場合は、前回の記事を読み返しておいてください。
ちょうど、「?」の働きを説明しやすいところまできましたので、このタイミングで説明しておきます。
まずは、以下の例を見てください。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$_ = "1.CGI 2.Perl 3.PHP";
if (/(.+[a-zA-Z]+)/) {
print $1;
}
exit;
このPerl/CGIプログラムを実行すると、「1.CGI 2.Perl 3.PHP」と表示されます。
これが何を表しているのかわかりますか?
これは、半角英大文字または小文字の前に、それいがいで何らかの1文字以上の文字が認められたときに成立するパターンマッチです。
さらに、パターン文字全体を「(」と「)」で囲んでいますから、マッチした部分が、特殊変数「$1」に代入され出力されるようになっています。
つまり、「$_」のどの部分がマッチしたかがわかるわけです。
このように、パターン文字全体を「(」と「)」で囲むと、自分が作成したパターンマッチが思ったような働きをしているか一目でわかるので、練習にはお勧めの方法ですよ。
話を戻しまして…。
上記例で、「$_」に代入されたすべての文字列が出力されたということは、すべての文字列にマッチしたということですよね。
これは、パターンマッチの性質上仕方ないことです。
パターンマッチでは、何も指定が無い限り、できるだけ最大マッチになるように動作する性質があるのです。
でも、これでは困る時だってあるわけですよね。
そんなときには「?」を使って、最小マッチに切り替えます。
具体的にはどの部分に「?」を追加すると思いますか?
「正解は次回に発表します!」とかいって無駄に引き伸ばしてもいいんですが、あまり意味が無いので、ここで正解を書いておきますね。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$_ = "1.CGI 2.Perl 3.PHP";
if (/(.+?[a-zA-Z]+)/) {
print $1;
}
exit;
こうすると、「1.CGI」のみが表示されるようになりますよ。
これが「?」の働きです。
寄り道は以上です。
本編に戻りますね。
パターン比較変数
ここまでパターンマッチを学習してきましたが、比較する文字列はすべて特殊変数「$_」に代入してきました。
基本的なことを学習する間は、Perl/CGIプログラムコードをなるべくシンプルにしたほうがわかりやすいので仕方の無いことですが、正直そろそろ飽きてきましたよね(苦笑)。
それにこのままでは、パターンマッチを使うためには常に、特殊変数「$_」を呼び出さなくてはいけませんしね。
実践向きではないわけですよ。
なので今度は、普通の単純変数を使ってパターンマッチを実行していきましょう。
パターンマッチ(1)
#!/usr/bin/perl
use strict;
print "Content-type: text/html\n\n";
my $string = "Perl/CGI";
if ($string =~ /Perl/) {
print "OK";
} else {
print "NO";
}
exit;
このPerl/CGIプログラムを実行すると「OK」と表示されます。
今度のパターンマッチは、特殊変数「$_」ではなく、単純変数「$string」と比較しています。
左辺に比較したい変数、右辺にパターンマッチを指定します。
そしてその結果を、if文で判断するのが常套手段です。
パターンマッチ部分を見てみると「$string =~ /Perl/」となっています。
これは、変数「$string」の中に、パターン文字列「Perl」が含まれていたら成立することを表しています。
変数「$string」の中には、「Perl/CGI」という文字列が格納されていますから、パターンマッチ成立ですね。
さらに、全体がif文で囲まれていますから、パターンマッチが成立したとき「真」という扱いになります。
したがって、「OK」が出力されたというわけです。
ちなみに、「$string =~ /Perl/」ですが、仮に変数「$string」ではなく、今までと同じように特殊変数「$_」と比較させたい場合は、「$_ =~ /Perl/」という感じになります。
もちろん、「/Perl/」のように、「$_」と「=~」を省略してパターンマッチのみを書いてもOKです。
パターンマッチ(2)
#!/usr/bin/perl
use strict;
print "Content-type: text/html\n\n";
my $string = "Perl/CGI";
if ($string !~ /Perl/) {
print "OK";
} else {
print "NO";
}
exit;
このPerl/CGIプログラムを実行すると「NO」と表示されます。
パターンマッチの「=~」部分を、「!~」に変更しました。
あとは何も変えていません。
実行結果から見てわかるように、意味が逆になりましたね。
つまり、変数「$string」の中に、「Perl」という文字列が含まれていなければパターンマッチ成立という感じに変わったわけです。
単純に意味が逆になっただけですから、わかりやすいですよね。
パターンマッチオプション
パターンマッチオプションを使うと、今まで学習してきましたパターンマッチの動きを一部変化させることができます。
いまいちイメージしづらいと思いますが、実際のパターンマッチを見ていただければわかります。
大小文字マッチ
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$_ = "Perl/CGI";
if (/perl/i) {
print "OK";
} else {
print "NO";
}
exit;
このPerl/CGIプログラムを実行すると「OK」と表示されます。
パターンマッチの後ろに「i」を指定することにより、パターン文字の大文字と小文字の区別をなくしています。
仮にパターンマッチ部分が、「/perl/」であれば「NO」が出力されます。
同じ「P」でも、大文字と小文字ではまったく別の文字として解釈されるからですね。
これは、今まで学習してきたことですからわかりますよね。
しかし、「/perl/i」のように「i」を指定することにより、大文字と小文字の区別がなくなりました。
つまり、「PERL」でも「pErL」でも、パターンマッチが成立するようになったというわけですね。
行マッチ
次は、行単位でマッチさせるという考え方について見ていきますが、ちょっとわかりにくいと思うので、まずは以下の例から見てください。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$_ = "Perl\nCGI";
if (/^CGI/) {
print "OK";
} else {
print "NO";
}
exit;
このPerl/CGIプログラムを実行すると「NO」と表示されます。
パターンマッチ部分「/^CGI/」が何を表しているのかはわかりますよね。
少し前にやりましたので簡単ですね。
「^」は、文字列の先頭を表しています。
つまり、もし先頭の文字列が「CGI」であったらマッチするといっているわけです。
これに対して、比較する文字列は「Perl\nCGI」ですから、パターンマッチは成立しないことがわかりますよね。
では次に、こちらの例を見てください。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$_ = "Perl\nCGI";
if (/^CGI/m) {
print "OK";
} else {
print "NO";
}
exit;
このPerl/CGIプログラムを実行すると「OK」と表示されます。
変更したところは、パターンマッチ部分に「m」を追加したことぐらいです。
あとは変わっていません。
パターンマッチ部分に「m」を指定すると、比較する文字列が複数行になっていた場合、それを認識した扱いをしてくれるようになります。
つまり、今回のように比較する文字列が「$_ = "Perl\nCGI";」のように、「"」で囲まれ、さらに改行を表す「\n」が使われていた場合…。
1行の文字列「Perl\nCGI」ではなく、2行の文字列で…。
1行目が「Perl」。
2行目が「CGI」。
と認識されるということです。
そして、2行目の先頭には文字列「CGI」がきていますから、「/^CGI/m」というパターンマッチが成立したというわけです。
ちょっとわかりにくい部分ですよね。
わからない場合は何度か読み返してみてください。
繰り返しマッチ
最後は、繰り返しマッチさせる方法についてみていきましょう。
#!/usr/bin/perl
print "Content-type: text/html\n\n";
$_ = "Perl/CGI";
while (/(.)/g) {
print $1;
}
exit;
このPerl/CGIプログラムを実行すると「Perl/CGI」と表示されます。
パターンマッチに「g」を指定すると、ひとつの文字列に対して繰り返しマッチさせることができます。
ざっと見て、何をしているのかわかりますか?
「g」は繰り返しマッチさせる指定だとわかれば、残りの「/(.)/」は先ほどやったばかりですのでわかりますよね。
「$_」内の文字列から、1文字マッチさせて「$1」に代入させています。
この処理にプラスして、 whileループ が指定してありますから、「$_」内の文字列「Perl/CGI」が、順番に「$1」に代入され出力されるということになります。
そして、すべての文字列にマッチしたらループが終了します。
実行結果だけではわかりにくいですが、何回ループしているかわかりますか?
特殊変数「$_」内の文字列「Perl/CGI」が8文字なので、単純に8回ですね。
以上でパターンマッチの基本的な話は終わります。
実はまだいろいろできることはあるんですが、この連載の分量をもってしても、これ以上はきついかと思うのでとりあえずは終了です。
正規表現に関してはこれからも出てくる機会はたくさんあるので、新しく出てきたものに関しては、そのつど説明していこうかと思います。
いやー、なんとなく予想はしていたんですが、やはり、正規表現は恐ろしく量がありますね(苦笑)。
編集後記
今回の編集後記は、冒頭で日本語の扱いについて注意すべきことを書きましたし、本編ではパターンマッチを学習したということで、おもいっきりベタな転回ではありますが(苦笑)。
「日本語を使ったパターンマッチで注意すべきこと」を書いていきます。
まぁ注意すべきことといっても、実は編集前記でも書きましたように、「Perlシステム側の日本語コードの読み間違いに注意しましょう」という落ちで終わってしまうのですが(苦笑)。
でもそれでは芸が無いですし、この編集後記を読む意味が無くなってしまうので、今回は少し変化を付けてお届けしたいと思います。
どんな変化かというと…。
今までは、文字化けや文字コードの読み間違いに関して、例題も出しやすく、また実際にトラブルも多いShift_jisコードばかり取り上げてきました。
そのせいもあって、この連載を読んでいるあなたは、Shift_jisコードを使うときは注意すると思うんですよね。
では、Shift_jisコード以外の文字コードに目を向けたとき、「他の文字コードではまったく文字コードの読み間違えは起こらないのか?」という疑問が生まれてきませんか?
これまでの流れを見ていると、Shift_jisコードばかりが悪いような扱いで書いてきましたから当然の疑問だと思うのですが。
答えから言ってしまうと、実はそうではないんです。
こればかりは、1文字に対して複数のバイト数を使用する言語の宿命みたいなものですから、「完全なもの」と条件付けてしまうと、結構高いハードルになってしまうのです。
すでに編集前記でお話しましたShift_jisコードは、そのハードルにとどかないことはお分かりですよね(苦笑)。
では今度は、EUCコードならどうでしょうか?
確かに、EUCコードはShift_jisコードに比べ文字コードの読み間違えが起こりにくい仕組みになっています。
半角カタカナも2バイト構成になっていますし、実際、Shift_jisコードでトラブルが起こっていたものでも、EUCコードに変えるだけで解決する場合が多いです。
知り合いのPerl/CGIプログラマーなんかは、「EUCコードでないと、こわくて世に出せない」と言っていました。
信頼性に関しても、Shift_jisコードを大きく上回るわけです。
では、先ほどの質問「EUCコードであれば、文字コードの読み間違えは起こらないのか?」というと…。
実はEUCコードも絶対ではありません。
かなり低い可能性ではありますが、EUCコードであっても、文字コードの読み間違えは発生します。
例えば、これを見てください。
#!/usr/bin/perl
print "Content-type: text/html; charset=euc-jp\n\n";
$_ = "パターンマッチテスト";
if (/好/) {
print "OK";
} else {
print "NO";
}
exit;
このPerl/CGIプログラムを実行すると「OK」と表示されてしまいます。
つまり、パターンマッチが成立してしまうわけです。
ではなぜそうなるのかを、いつものように16進コードに置き換えて考えてみましょう。
まず「好」の16進コードは「\xB9\xA5」という2バイト文字で表されます。
そして、パターンマッチが成立したということは、「$_」内の比較する文字列のどれかに、この16進コードの並びがあるわけですよね。
実は「テスト」という文字列が問題なのです。
正確には「ス」と「ト」の並びが問題です。
「スト」の16進コードは、「\xA5\xB9\xA5\xC8」このようになっています。
「好」を表す「\xB9\xA5」がバッチリ入っていますよね。
「ス」の2バイト目の「\xB9」。
「ト」の1バイト目の「\xA5」。
「ス」と「ト」、バラバラに使っていればこのようなことは起こらないんですが、並べて使ったがために、このように「好」とマッチしてしまったわけですね。
バラバラに食べていればおなかを壊さなかったのに、一緒に食べたがためにおなかを壊してしまったような感じです。
まぁでも、これは特殊なケースですから、正直そんなに意識する必要はないと思いますよ。
もちろんこのような現象は、探せば他にもあるとは思うんですが、文字コードの読み間違えが発生する確率を考えれば、ものすごく低い話になるとは思いませんか?
もちろん、完璧を目指すことは大切ですよ。
しかし、ほとんど起こらないであろうケースばかり想定して、その結果を云々するのはいかがなものかと思うんですよね。
前にも書きましたが、使用する文字コードというのは、プログラマー側で自由に決めるべきだと思っています。
Shift_jisでもEUCでも、その性質を理解した上でつかっているのであればどちらでも問題ないと思います。
それに実は、このEUCコードの読み間違えというのは、すでに有名?かどうかはわかりませんが、回避する方法というのがあります。
ここでその方法を紹介したいのですが、この方法を読者の皆さんに理解していただくためには、もっと、正規表現と16進コードに詳しくならないときついと思うので、それはまた別の機会に紹介しますね。
このことから何が言いたいのかというと…。
皆さん文字コードは何を使うかで悩んでいますが、実は、「文字コードの性質を理解した上でどう使っていくか」ということの方が大切だと言いたいわけです。
たくさんある道具の中から「何を使うか」ということも大切ですが、最終的には、「その選んだ道具をどう使っていくのか」というところにかかってくるのではないかと思うんです。
いろんな考え方があるとは思うんですが、個人としてはこう思っています。
あなたはどう思いますか?
今回の学習は以上です。
ありがとうございました。
<戻る>