my local our

やっとここにきた。

ここでスコープをおさらい。

http://d.hatena.ne.jp/perlcodesample/20080310/1205162964

my

まずはmyから。

http://www.geocities.jp/ky_webid/perl5/025.html

変数の宣言時にいつも付けている「my」は、変数のスコープを基本的に { } の内部に限定します。そのため関数内で宣言すると、関数の { } がスコープとなります。このスコープ外からはアクセスできない(見えない)のです。

要は、JavaScriptでいうlocal変数ってことかな。

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


# my
my $num = 10;
print "num = $num\n";

# スコープ
print "スコープ1\n";
{
	my $num2 = 20;
	print "num = $num\n";
	print "num2 = $num2\n";
}

print "スコープ2\n";
{
	my $num2 = 30;
	print "num2 = $num2\n";

	sub scope2sub
	{
		return $num2;
	}
}

print "スコープ2の中のnum2 = " . scope2sub() . "\n";
C:\MyWorks\Perl\mylocalour>perl my1.pl
num = 10
スコープ1
num = 10
num2 = 20
スコープ2
num2 = 30
スコープ2の中のnum2 = 30

最後のやつはクロージャと一緒なのでわかるんだけど、スコープの中の関数を外からいじれるのがいまいちよくわかんないけど、関数はスコープの階層は関係ないってことなのかな。

local

http://d.hatena.ne.jp/perlcodesample/20080309/1205078496

# localの役割は、パッケージ変数を一時的に保存して、
# 後で、復元することにある。

# 他言語のローカル変数とは、何の関係もない。

# lacal の後にくる変数は、パッケージ変数であって、レキシカル変数ではない
# localは、一見、変数宣言のように見えるが、変数宣言ではない。
# 変数宣言に使えるのは、Perlでは、my と our だけである。

http://www.geocities.jp/ky_webid/perl5/025.html

local変数は、外側のスコープに同じ名前の変数があるとき、その値を記憶したまま、別の値を割り当てます。

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


my $num1 = 50;
print "num1 = $num1\n";
{
	local $num1 = 100;
	print "num1 = $num1\n";

}

print "num1 = $num1\n";
C:\MyWorks\Perl\mylocalour>perl local1.pl
Can't localize lexical variable $num1 at local1.pl line 9.

なんでエラーでんのかなあと思ったら

# lacal の後にくる変数は、パッケージ変数であって、レキシカル変数ではない
# localは、一見、変数宣言のように見えるが、変数宣言ではない。
# 変数宣言に使えるのは、Perlでは、my と our だけである。

パッケージ変数ってなんぞって思って調べたら

http://d.hatena.ne.jp/perlcodesample/20080308/1204953841

# パッケージ変数
#     ・パッケージ変数とは、名前空間に属するグローバル変数である。
#     ・つまり、パッケージ変数は、修飾名(パッケージ名)を持ち、
#       ソースコードのどの位置からでも参照できるということです。
#
#     ・パッケージ名を含めて記述した変数名を完全修飾名と呼びます。
#       ( 完全修飾名 $SomePackage::package_var1 )
#
#      ・パッケージ名は大文字ではじめる。単語の区切りも大文字にする。

なんでグローバル変数を使ってるのか理解できた。
というわけで、パッケージ変数とやらを作ってみたけども

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

package pkg;
$pkg::num1 = 50;
print "num1 = $pkg::num1\n";
{
	local $num1 = 100;
	print "num1 = $num1\n";
}

print "num1 = $pkg::num1\n";
C:\MyWorks\Perl\mylocalour>perl local1.pl
Variable "$num1" is not imported at local1.pl line 9.
Variable "$num1" is not imported at local1.pl line 10.
Global symbol "$num1" requires explicit package name at local1.pl line 9.
Global symbol "$num1" requires explicit package name at local1.pl line 10.
Execution of local1.pl aborted due to compilation errors.

エラーが出るのはいいんだが、なぜエラー出るのかが理解できないので、とりあえず先に進むためにここは妥協&後回し。

#!C:/Perl/bin/perl

#use strict;
#use warnings;


$num = 500;
print "$num\n";

func();

sub func
{
	local $num = 100;
	print "$num\n";
}

print "$num\n";
C:\MyWorks\Perl\mylocalour>perl local1.pl
500
100
500

やってみればわかるんだけど、これって何のために使うのかがよくわからない。
関数の引数で値渡しするのと同じイメージしか思い浮かばないんだけどどうなんだろうなあ。
とりあえず今のレベルでは使い道が思い浮かばないのでそれまでは使わない方向で。


ということで時間切れ、ourは次回ということで。