- ベストアンサー
My関数の有効な使い方。
初心者が分からない理由には、なりませんが、 My関数の有効な使い方が分かりません。 My関数を使わなくてもできる事が多数で、My関数で ないとできない処理ってあるんでしょうか? My関数を使う理由は、やっぱりサーバのメモリーの 節約のためなんでしょうか? メモリーの節約は、変数を使い終えた後、空白を 代入する方法とどれくらい違うんでしょうか? (空白を入れるだけでは、メモリーの場所を確保した ままになる・・・と読んだ気もします。) あまり頭はよくないので、わかりやすい言葉で説明して 頂ければ、幸いです。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
ちょっと伝わりきらなかったみたいなので、もう一度補足です。 まず、確かに.=である必然は無いです、そうではなくて、例なので。スコープの意味が捕らえやすいかなと思ったのですが。その意味では、注意深く書きさえすれば、myのお世話になる必要なんて全くないわけです。使いたくないなら使わなければよい、使いたいならば使えばよい、それだけです。変数が自由なのと同じで、それもPerlの柔軟性です。好きなように書いてください、Perlではそれが許されています。 myを使う理由は、前にも書いた通り楽をする為であって、メモリの節約は副次的なものです。多分、メモリの節約の為にmyを使う人は多くないと思います。(多分。) myは変数を宣言するのではなくて、スコープを設定しているものと思ってください。スコープを設定する意味は私のような怠惰で不用心な人が楽をする為であって、必然ではありません。myはその為の関数なので、スコープに用が無いなら使う必要はありません。(ちなみに私もPerlから入ったので違和感を覚えましたが、今ではmyが無ければ暮らす事すら…とまでは言わないもの、それくらい使います。) myやuse strictは、安全でバグの少ない、可読性が高く保守のしやすいコードを書く手助けを(ちょっとだけ)してくれます。カプセル化やオブジェクト指向プログラミングへの可能性を広げてくれます。が、それも安全なコードを書く為の一つの方法に過ぎません。 あと、use strictの使用をお勧めしましたが、保守のしやすいコードを書く重要性に目を向けるきっかけになるかな、と思った為です。これも自由です。
その他の回答 (3)
- hikomin
- ベストアンサー率63% (40/63)
ごめんなさい、補足です。myで定義される変数の有効範囲はブロック内です。ブロックとは、中カッコ{}で囲まれた範囲です。ifやループで使う中カッコがブロックですし、もちろんサブルーチンのものもブロックです。別にifやサブルーチンが無ければ使ってはならないものではなくて、有効範囲を絞る為だけにブロックを作る事も出来ます。つまり、プログラム内に突然、ifでもforでもなく { my $buffer = xxx; # なにか処理している } とかがあっても問題ありません。
- hikomin
- ベストアンサー率63% (40/63)
myを使う理由は、プログラミングが楽になるから、です。暇な時に、と言う事なのでのんびり書きましたので(=長い)暇な時にお読みください。 myを使って変数を局所化すると、うっかり同じ変数を使った為におかしくなるようなミスを減らす事が出来ます。例えば、配列の内容を順に表示する事を考えます。ちょっとわざとらしいですが… -- @files = ( 'file1.txt', 'file2.txt', 'file3.txt' ); $i = 1; foreach $file (@files){ $buffer .= sprintf "%03d>%s¥n", $i++, $file; print $buffer; } -- 処理は冒頭に通し番号を付けているだけ。簡単な例なので問題点がすぐ分かったかも知れませんが、$bufferをループごとにクリアしていないので、同じ内容が何度も表示される事になります。この例だと file1.txt, file1.txt, file2.txt, file1.txt, file2.txt, file3.txt と言う順に内容表示されます。ところが、myで生存範囲を限定しておけば、こんな事は起こりません。 -- @files = ( 'file1.txt', 'file2.txt', 'file3.txt' ); $i = 1; foreach $file (@files){ my $buffer .= sprintf "%03d>%s¥n", $i++, $file; print $buffer; } -- これで希望通り動作します。もちろん、毎回$bufferをクリアすれば良いだけですが、局所化し生存範囲を把握しておく事で、うっかり前の内容が使い回されると言ったミスが無くなるわけです。 グローバル変数はどこからでも変更される可能性があるので、その内容がどこで変わるのかを常に気にかけなければなりません(サブルーチンでも変更出来るので、上から順にとは行かないのが大変です)が、局所化すればその範囲内でしか変数を使えないので、範囲外では余計なことを考えずに済みます。メモリなんてどうにでもなりますが(いや、軽視しろと言う意味ではないですが)プログラム全体の変数の状況を把握し続ける労力と時間は率直に惜しいと思いますがどうでしょうか。 他には、use strict;と組み合わせた時の効果も利点です。use strict;はPerlのチェックを厳しくするもので、変数を使う時にはmyやourでレキシカルなのかグローバルなのか決めておかなければなりません。新しい変数を使うたびにmyとかourが必要になるのでちょっと面倒に思うかも知れませんが、これを使うとうっかり綴りミスを発見する事が出来ます。 -- $test = ' test1 '; $text .= ' test2 '; # $testと書くつもりが$textと書いた…新しく$textが作成される print $test; exit; -- 出力はtest1だけですので、何かおかしいな?と言う風になります。がPerlは何がおかしいかは教えてくれません。この例では近場に原因があるのですぐ分かりますが、数百、数千行のプログラムからこうしたミスを見つけるのは、なかなか大変な作業になります。そこでuse strictを宣言しておきます。 -- use strict; my $test = ' test1 '; $text .= ' test2 '; # $testと書くつもりが$textと書いた…$textは宣言されていないのでエラーとなる print $test; exit; -- コマンドラインで実行するとGlobal symbol "$text" requires explicit package name at test.pl line 3.とエラーが出て、つづりをミスした事がすぐに分かります。無論CGIではサーバエラーが表示されます。 少し使ってみないとその感覚が掴みにくいとも思います。use strict;はステップアップに一役買う(というか使い捨てでないプログラムを組むつもりなら使う事が推薦されている)ので、最初は面倒ですがこれを機会に使ってみて、myに慣れてみるのはいかがでしょう。使ううちに変数の有効範囲(スコープ)の理解も深まると思います。
補足
変数の誤字は、実行時オプションで -Tw をつけて only onceでチェックしてるし、スクリプトも $buffer = sprintf "%03d>%s¥n", $i++, $file; すれば、とくに問題はなさそうな・・・。 あえて、".="でデーターを追加する必要もないと 思うんですが。g^^; まぁ、ループを抜けても、$bufferの内容はメモリー内に 残ってしまいますが。 --結果------------ 001>file1.txt¥n 002>file2.txt¥n 003>file3.txt¥n ------------------ と、出るし。 Visual Basic等、他のプログラムの経験がないので、 変数を宣言すると言う事には疎いのかもしれません。 でも、変数が柔軟で簡単なのがPerlの魅力でもあるし。 My関数の、基本的な使い方は分かるんです。 My関数を使うと、とても楽。 もしくは、My関数じゃないと、うまく処理できない、 具体例があれば、見識も変わるとおもうんですが・・・。 やっぱり、小さいスクリプトしか作っていないので、 ぴんとこないのかもしれません。 use strictを使った方が安全だよ。 と言われてしまえば、その通りなんですが。。
Perlですね(CGIと言ってもPerlとは限りませんので、言語を明示した方が良いです)。 my関数は、変数を局所化(宣言したサブルーチン以外では使えないようにする)するためにあります。 あまり必要ないようにも見えますが、変数を局所化するのはとっても重要です。 たとえば、サブルーチンが何個も何個も出来てしまった場合、それぞれのサブルーチンで局所化していない変数(=グローバル変数)をたくさん使ってしまうと、"この変数はどこの何を変更するのか、どこで初期化されるのか"が、大変分かりづらくなってしまうのです。 また、しっかり変数を宣言することで、"このサブルーチンではこれらの変数を使うんだぞ"と明示することが出来ます。自分が久しぶりにそのスクリプトをさわるとか、他人が見るときに、その方が理解しやすくなりますね(わたしはこれを全くしていない人のCGIを見せてもらったことがありますが、どの変数がどこに関連づけられていて、どこで初期化されるのかが分かりづらく、非常に読みづらかったです)。 もちろん、メモリの節約の意味もあるでしょうが、主に視認性を上げるために、しっかり宣言しておくべきではないかと思います。 あと、空白を代入する件ですが、その通りです。メモリの場所は確保したままになります。undefと言う関数を使うまで、そのメモリは解放されません。
お礼
視認性は、考えていませんでした。 私にとっては、新しい見解です。 最近はサーバも高性能・大量のメモリーを搭載されて、 いると思うので、軽視している訳ではありませんが、 個人のHPでいきなり、巨大なファイルを読み書きする わけではないので、あまり気にしてませんでした。 それよりは、汚染とか、セキュリティーの方に力をいれて 疲れてしまって。^^ 正直な話、まだmy関数はピンと来てません。 そのままの変数を使った方が、直感的で分かり安いかな。 今の所、my変数を使わないとダメって処理が、私の中 では、ないのも事実ですし。 でも、確かにmy関数を使わないと似たような変数が 多数できるのは、分かります。 それがメモリーの無駄遣いにつながるのかなー、と 気づいては、いたのですが。 ありがとうございました。
補足
あ、そうです。Perlです。 CGIは、Common Gateway Interfaceでしたね。^^; つい、CGI=Perlな気がして。 他にも、RubyやCもCGIでしたね。
お礼
なんども、投稿ありがとうございました。 今の所、安全性には惹かれつつ、my関数の使い方は 分かるのですが、使わないのが、現実です。^^ 私は記憶力が人より、悪い方なので、同じ変数名が 出てくると、混乱してしまうのです。 ここで、そういうのも自由と、少しだけですが、 後押しをしてくれたので、もうしばらくmy関数を 使わない方向で・・・。^^;