
=encoding utf-8

=head1 NAME

Data::Util::JA - データとデータ型のためのユーティリティ集

=head1 VERSION

This document describes Data::Util version 0.29_01

=head1 SYNOPSIS

	use Data::Util qw(:validate);

	sub foo{
		# they will die if invalid values are supplied
		my $sref = scalar_ref(shift);
		my $aref = array_ref(shift);
		my $href = hash_ref(shift);
		my $cref = code_ref(shift);
		my $gref = glob_ref(shift);
		my $rref = regex_ref(shift);
		my $obj  = instance(shift, 'Foo');
		# ...
	}

	use Data::Util qw(:check);

	sub bar{
		my $x = shift;
		if(is_scalar_ref $x){
			# $x is an array reference
		}
		# ...
		elsif(is_instance $x, 'Foo'){
			# $x is an instance of Foo
		}
		# ...
	}

	# miscelaneous
	use Data::Util qw(:all);

	my $ref_to_undef = anon_scalar();
	$x = anon_scalar($x); # OK

	my $stash = get_stash('Foo');

	install_subroutine('Foo',
		hello  => sub{ "Hello!\n" },
		goodby => sub{ "Goodby!\n" },
	);

	print Foo::hello(); # Hello!

	my($pkg, $name) = get_code_info(\&Foo::hello); # => ('Foo', 'hello')
	my $fqn         = get_code_info(\&Foo::hello); # => 'Foo::bar'

	uninstall_subroutine('Foo', qw(hello goodby));

	print neat("Hello!\n"); # => "Hello!\n"
	print neat(3.14);       # => 3.14
	print neat(undef);      # => undef

=head1 DESCRIPTION

このモジュールはデータとデータ型のためのユーティリティ関数を提供します。

ユーティリティはチェック関数群と検証関数群とその他の関数群があります。
チェック関数群は値の型を調べ，真偽値を返す機能を提供します。
検証関数群は値の型を調べ，真であればその値自身を返し，
偽であれば致命的エラーとなる機能を提供します。
その他の関数群は，無名スカラーリファレンスの生成やシンボルテーブルの操作，
コードリファレンスの操作などの機能を提供します。

=head1 INTERFACE

=head2 Check functions

チェック関数群はC<:check>インポートタグによって導入できます。これらはある値
の型が目的の型であれば真を，そうでなければ偽を返します。

また，これらの関数はオーバーロードマジックも調べます。たとえば，C<${}>が
オーバーロードされているオブジェクトは，スカラーリファレンスとして扱われます。

リファレンスの型チェックをする関数は，オブジェクトリファレンスに対しては，
オーバーロードされていない限り常に偽を返します。
これは，オブジェクトの実装に依存するコードを書かないようにするためです。

=over 4

=item is_scalar_ref(value)

スカラーリファレンスかどうかのチェックを行います。

=item is_array_ref(value)

配列リファレンスかどうかのチェックを行います。

=item is_hash_ref(value)

ハッシュリファレンスかどうかのチェックを行います。

=item is_code_ref(value)

コードリファレンスかどうかのチェックを行います。

=item is_glob_ref(value)

グロブリファレンスかどうかのチェックを行います。

=item is_regex_ref(value)

C<qr//>によって作られる正規表現かどうかのチェックを行います。

=item is_instance(value, class)

I<class>のインスタンスかどうかのチェックを行います。

C<< Scalar::Util::blessed($value) && $value->isa($class) >>というコードと
ほぼ等価です。

I<class>が未定義値またはリファレンスであれば致命的エラーとなります。

=back


=head2 Validating functions

検証関数はC<:validate>タグによって導入できます。これらはチェック関数と
同じ方法でチェックを行います。
ただし，その結果が真であれば第一引数をそのまま返し，
偽であれば致命的エラーとなります。

これらの関数もオーバーロードマジックをチェックします。

=over 4

=item scalar_ref(value)

スカラーリファレンスかどうかの検証を行います。

=item array_ref(value)

配列リファレンスかどうかの検証を行います。

=item hash_ref(value)

ハッシュリファレンスかどうかの検証を行います。

=item code_ref(value)

コードリファレンスかどうかの検証を行います。

=item glob_ref(value)

グロブリファレンスかどうかの検証を行います。

=item regex_ref(value)

C<qr//>によって作られる正規表現かどうかの検証を行います。

=item instance(value, class)

I<class>のインスタンスかどうかの検証を行います。

I<class>が未定義値またはリファレンスであれば致命的エラーとなります。

=back

=head2 Micellaneous utilities

その他，個別にインポートできるいくつかのユーティリティ関数があります。

=over 4

=item anon_scalar()

C<undef>を参照する匿名スカラーリファレンスを生成します。

=item anon_scalar(value)

I<value>を参照する匿名スカラーリファレンスを生成します。

=item neat(value)

I<value>を表示に適するよう整形した文字列を返します。
C<<do{ defined($value) ? qq{"$value"} : 'undef' }>>を置き換える機能
として提供されます。

=item get_stash(package)

スタッシュ B<stash> と呼ばれるI<package>のシンボルテーブルハッシュが
存在すれば，そのスタッシュを返します。

C<< do{ no strict 'refs'; \%{$package.'::'} } >>というコードに似ていますが，
I<package>が存在しなければそのスタッシュは生成せずC<undef>を返します。
なお，I<package>が未定義値またはリファレンスのときもC<undef>を返します。

=item install_subroutine(package, name => subr [, ...])

サブルーチンI<subr>をI<package>にI<name>としてインストールします。

C<< do{ no strict 'refs'; *{$package.'::'.$name} = \&subr; } >>というコードと
ほぼ等価です。さらに，I<subr>が匿名サブルーチンであればI<package>に
名前付きサブルーチンI<&package::name>として配置します。

サブルーチンを再インストールするときは，C<< no warnings 'redefine' >>
ディレクティブを使ってください。

	no warnings 'redefine';
	install_subrouitne($package, $name => $subr);

I<package>かI<name>が未定義値またはリファレンスであれば致命的エラーとなります。
I<subr>がコードリファレンスでないときも致命的エラーとなりますが，
オーバーロードマジックは考慮されます。

なお，Pure Perl版のコードでは匿名サブルーチンの配置は行いません。

=item uninstall_subroutine(package, names ...)

サブルーチンI<name>をパッケージI<package>から削除します。

C<< undef &subr >>がC<&subr>を未定義にして型グロブのコードスロットを
そのままにするのに対して，C<uninstall_subroutine>は型グロブのコードスロットを
空にします。

これはC<Sub::Delete::delete_sub()>に似ていますが，複数のサブルーチンを一度に
削除できます。

=item get_code_info(subr)

コードリファレンスI<subr>のパッケージと名前のペアを返します。
これはC<Sub::Identify::get_code_info()>とほぼ同じ機能です。
ただし，スカラーコンテキストでは完全修飾名を返します。

=item curry(subr, args and/or placeholders)

=item wrap_subroutine(subr, ...)

=item subroutine_modifier(subr, ...)

=item mkopt(input, moniker, require_unique, must_be)

I<input>を元に配列リファレンスを作成します。

これはC<Data::OptList::mkopt()>に似ています。それに加えて，I<must_be>は
名前と型のペアからなるハッシュリファレンスでもかまいません。

=item mkopt_hash(input, moniker, must_be)

I<input>を元にハッシュリファレンスを作成します。

これはC<Data::OptList::mkopt_hash()>に似ています。それに加えて，I<must_be>は
名前と型のペアからなるハッシュリファレンスでもかまいません。

=back

=head1 DISCUSSIONS

=head1 What is a X-reference?

「Xのリファレンス」とは何を指すのでしょうか。ここではハッシュリファレンスを例にとって考えます。
まず，判断要素は以下の3つを想定します。

=over 4

=item 1

C<ref($x) eq 'HASH'>

=item 2

C<Scalar::Util::reftype($x) eq 'HASH'>

=item 3

C<overload::Method($x, '%{}')>

=back

C<ref()>は非常に高速なので，実用上はこれで事足りることが多いと思われます。しかし，これはオーバーロードマジックを考慮しません。

C<reftype()>を使うべきではありません。$xがオブジェクトである場合，オブジェクトの実装型を参照し，カプセル化を壊してしまうことになるからです。

そしてC<overload::Method>が捕捉するのは，オブジェクトをある型のリファレンスとみなしてよい特殊なケースです。

なお，直接$xをハッシュリファレンスとみなして参照すること(C<< $x->{$key} >>)は避けるべきです。これは$xがハッシュリファレンスでない場合に正しく致命的エラーを発生させますが，ブレスされたハッシュリファレンスのときにはアクセスが成功します。しかし，そのアクセスの成功はオブジェクトの実装に依存しています。

さて，それではC<is_hash_ref()>は何を調べればいいのでしょうか。回答の一つはC<Params::Util>が示しています。Version 0.35の時点では，C<P::U::_HASH>は(1)を，C<P::U::_HASHLIKE>は(2)と(3)をチェックします。しかし先に述べたように，(1)は高速ですがオーバーロードマジックを考慮しないので不完全であり，(2)はオブジェクトのカプセル化を壊すため使うべきではありません。このように考えると，C<is_hash_ref()>は(1)と(3)によるチェックを行うのが正しい実装ということになります。

したがって，C<is_hash_ref()>ではC<ref()>とC<overload::Method()>を使ってリファレンスの型を調べます。C<is_scalar_ref()>，C<is_array_ref()>，C<is_code_ref()>，C<is_glob_ref()>も同様です。

=head1 DEPENDENCIES

Perl 5.8.1 or later.

=head1 BUGS AND LIMITATIONS

No bugs have been reported.

Please report any bugs or feature requests to the author.

=head1 SEE ALSO

L<Scalar::Util>.

L<overload>.

L<Params::Util>.

L<Sub::Install>.

L<Sub::Identify>.

L<Sub::Delete>.

L<Sub::Curry>.

L<Class::Method::Modifiers>.

L<Data::OptList>.

=head1 AUTHOR

Goro Fuji E<lt>gfuji(at)cpan.orgE<gt>

=head1 LICENSE AND COPYRIGHT

Copyright (c) 2008, Goro Fuji E<lt>gfuji(at)cpan.orgE<gt>. Some rights reserved.

This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

=cut

