Perlのモジュール側のクロージャで、値を保持し続けてほしかった

## 何がしたかったか
`use`しているモジュール側にクロージャがある場合、何度呼び出しても値を保持しておいて欲しいなーって思いました。

## 元のコード

```pl:closer.pl
use strict;
use warnings;
use CloserModule;

my $closer_module = CloserModule->new();
print $closer_module->get_count(), ', ';
print $closer_module->get_count();

exit;
```

```pl:CloserModule
package CloserModule;
use strict;
use warnings;

sub new {
	my $pkg = shift;
	bless {}, $pkg;
}
sub get_count{
	my $self = shift;
	my $closer = sub {
		my $count = 0;
		return sub {
			$count++;
			return $count;
		};
	}->();
	return $closer->();
}
1;
```

```:結果
1, 1
```

closer.pl側でget_countを呼び出すたびに`$closer`という変数が初期化されているので、毎回`$count`が0になってしまいます。
できれば`$count`を保持し続けてほしいな、と思ったのでした。


## 修正したコード

偉大な先人たちのモジュールを見ていると、変数がサブルーチンの外で宣言・初期化されていることがよくあったので、真似してみました。

```pl:closer.pl
use strict;
use warnings;
use CloserModule;

my $closer_module = CloserModule->new();
print $closer_module->get_count(), ', ';
print $closer_module->get_count();

exit;
```

```pl:CloserModule
package CloserModule;
use strict;
use warnings;

sub new {
	my $pkg = shift;
	bless {}, $pkg;
}
my $closer = sub {
	my $count = 0;
	return sub {
		$count++;
		return $count;
	};
}->();
sub get_count{
	my $self = shift;
	return $closer->();
}
1;
```

```:結果
1, 2
```

変数`$closer`をサブルーチンの外で宣言・初期化しているので、何度`get_count`を呼んでも`$count`の値は保持されたまま（`$count`が再度宣言・初期化されないまま）になります。


## ついでに

```pl:closer.pl
use strict;
use warnings;
use CloserModule;

my $closer_module = CloserModule->new();
print $closer_module->get_count(), ', ';
print $closer_module->get_count(), ', ';

my $closer_module2 = CloserModule->new();
print $closer_module2->get_count(), ', ';
print $closer_module2->get_count();

exit;
```

とした場合。

```:結果
1, 2, 3, 4
```

となりました。
つまり、サブルーチン外の変数は`new`した際に初期化されるのではなくて、`use`した際に初期化されて、モジュール側に値が残り続けるということなのですね。
当然といえば当然ですが。。。


## newした際には$countを0からスタートさせたい

```pl:CloserModule
package CloserModule;
use strict;
use warnings;

my $closer;

sub new {
	my $pkg = shift;
	$closer = sub {
		my $count = 0;
		return sub {
			$count++;
			return $count;
		};
	}->();
	bless {}, $pkg;
}
	
sub get_count{
	my $self = shift;
	return $closer->();
}
1;
```

のように、`$closer`はサブルーチンの外で宣言をして、`new`の中で中身を代入してあげれば、`new`した際に`$count`が（というか、`$closer`自体が）初期化されます。
これで、結果は下記の通りになりました。

```:結果
1, 2, 1, 2
```

しかし、

```pl:closer.pl
use strict;
use warnings;
use CloserModule;

my $closer_module = CloserModule->new();
print $closer_module->get_count(), ', ';
print $closer_module->get_count(), ', ';
print $closer_module->get_count(), ', ';

my $closer_module2 = CloserModule->new();
print $closer_module2->get_count(), ', ';
print $closer_module2->get_count(), ', ';

print $closer_module->get_count();	#(1)

exit;
```

とした場合に、(1)の部分では4が返るのを期待していましたが、実際には、、、

```:結果
1, 2, 3, 1, 2, 3
```

となりました。
サブルーチン外の変数は影響範囲が大きいですね。


## 前項の(1)で4が返るようにする
思いついたのは、おとなしく`bless`すれば？　という事くらいしかありませんでした。

```pl:CloserModule.pm
package CloserModule;
use strict;
use warnings;
sub new {
	my $pkg = shift;
	bless {
		closer => sub {
			my $count = 0;
			return sub {
				$count++;
				return $count;
			};
		}->(),
	}, $pkg;
}
sub get_count{
	my $self = shift;
	
	#return $closer->();
	return $self->{closer}->();
}

1;
```

でもこれだったら普通に

```pl:CloserModule.pm
package CloserModule;
use strict;
use warnings;
sub new {
	my $pkg = shift;
	bless {
		count => 0,
	}, $pkg;
}
sub get_count{
	my $self = shift;
	
	return ++$self->{count};
}

1;
```

で良かったりします。


なんか他に方法ないのかなー？
もちろん、`bless`でもいいんですけどね。

何はともあれ、想定とは違う部分でいろいろ勉強になりました。