NAME
Util::Any - to export any utilities and to create your own utilitiy module
SYNOPSIS
use Util::Any -list;
# you can import any functions of List::Util and List::MoreUtils
print uniq qw/1, 0, 1, 2, 3, 3/;
If you want to choose functions
use Util::Any -list => ['uniq'];
# you can import uniq function only, not import other functions
print uniq qw/1, 0, 1, 2, 3, 3/;
If you want to import All kind of utility functions
use Util::Any -all;
my $o = bless {};
my %hash = (a => 1, b => 2);
# from Scalar::Util
blessed $o;
# from Hash::Util
lock_keys %hash;
If you want to import functions with prefix(ex. list_, scalar_, hash_)
use Util::Any -all, {prefix => 1};
use Util::Any -list, {prefix => 1};
use Util::Any -list => ['uniq', 'min'], {prefix => 1};
print list_uniq qw/1, 0, 1, 2, 3, 3/;
If you want to import functions with your own prefix.
use Util::Any -list => {-prefix => "l_"};
print l_uniq qw/1, 0, 1, 2, 3, 3/;
If you want to import functions as different name.
use Util::Any -list => {uniq => {-as => 'listuniq'}};
print listuniq qw/1, 0, 1, 2, 3, 3/;
When you use both renaming and your own prefix ?
use Util::Any -list => {uniq => {-as => 'listuniq'}, -prefix => "l_"};
print listuniq qw/1, 0, 1, 2, 3, 3/;
print l_min qw/1, 0, 1, 2, 3, 3/;
# the following is NG
print l_uniq qw/1, 0, 1, 2, 3, 3/;
DESCRIPTION
For the people like the man who cannot remember uniq
function is in whether List::Util or List::MoreUtils. And for the newbie who don't know where useful utilities is.
Perl has many modules and they have many utility functions. For example, List::Util, List::MoreUtils, Scalar::Util, Hash::Util, String::Util, String::CamelCase, Data::Dumper etc.
We, Perl users, have to memorize modules name and their functions name. Using this module, you don't need to memorize modules name, only memorize kinds of modules and functions name.
And this module allows you to create your own utility module, easily. You can create your own module and use this in the same way as Util::Any like the following.
use YourUtil -list;
see CREATE YOUR OWN Util::Any
, in detail.
HOW TO USE
use Util::Any (KIND)
use Util::Any -list, -hash;
Give list of kinds of modules. All functions in moduls are exporeted.
use Util::Any KIND => [FUNCTIONS], ...;
use Util::Any -list => ['uniq'], -hash => ['lock_keys'];
Give hash whose key is kind and value is function names as array ref. Selected functions are exported.
you can write it as hash ref.
use Util::Any {-list => ['uniq'], -hash => ['lock_keys']};
use Util::Any ..., {OPTION => VALUE};
Util::Any can take last argument as option, which should be hash ref.
- prefix => 1
-
add kind prefix to function name.
use Util::Any -list, {prefix => 1}; list_uniq(1,2,3,4,5); # it is List::More::Utils's uniq function
- module_prefix => 1
-
see "PREFIX FOR EACH MODULE". Uti::Any itself doesn't have such a definition.
- smart_rename => 1
- debug => 1/2
-
Util::Any doesn't say anything when loading module fails. If you pass debug value, warn or die.
use Util::Any -list, {debug => 1}; # warn use Util::Any -list, {debug => 2}; # die
EXPORT
Kinds of functions and list of exported functions are below. Note that these modules and version are on my environment(Perl 5.8.4). So, it must be diffrent on your environment.
scalar
from Scalar::Util (1.19)
blessed
dualvar
isvstring
isweak
looks_like_number
openhandle
readonly
refaddr
reftype
set_prototype
tainted
weaken
hash
from Hash::Util (0.05)
hash_seed
lock_hash
lock_keys
lock_value
unlock_hash
unlock_keys
unlock_value
list
from List::Util (1.19)
first
max
maxstr
min
minstr
reduce
shuffle
sum
from List::MoreUtils (0.21)
after
after_incl
all
any
apply
before
before_incl
each_array
each_arrayref
false
first_index
first_value
firstidx
firstval
indexes
insert_after
insert_after_string
last_index
last_value
lastidx
lastval
mesh
minmax
natatime
none
notall
pairwise
part
true
uniq
zip
string
from String::Util (0.11)
crunch
define
equndef
fullchomp
hascontent
htmlesc
neundef
nospace
randcrypt
randword
trim
unquote
from String::CamelCase (0.01)
camelize
decamelize
wordsplit
debug
from Data::Dumper (2.121)
Dumper
EXPORTING LIKE Sub::Exporter
This featrue is not enough tested. and only support '-prefix' and '-as'.
use UtilSubExporter -list => {-prefix => 'list__', min => {-as => "list___min"}},
# The following is normal Sub::Exporter importing
greet => {-prefix => "greet_"},
'askme' => {-as => "ask_me"};
Check t/lib/UtilSubExporter.pm, t/10-sub-exporter-like-epxort.t and t/12-sub-exporter-like-export.t
CREATE YOUR OWN Util::Any
Just inherit Util::Any and define $Utils hash ref as the following.
package Util::Yours;
use Clone qw/clone/;
use Util::Any -Base; # or use base qw/Util::Any/;
our $Utils = clone $Util::Any::Utils;
push @{$Utils->{-list}}, qw/Your::Favorite::List::Utils/;
1;
In your code;
use Util::Yours -list;
$Utils STRUCTURE
overview
$Utils => {
# simply put module names
-kind1 => [qw/Module1 Module2 ..../],
-# Module name and its prefix
-kind2 => [ [Module1 => 'module_prefix'], ... ],
# limit functions to be exported
-kind3 => [ [Module1, 'module_prefix', [qw/func1 func2/] ], ... ],
# as same as above except not specify modul prefix
-kind4 => [ [Module1, '', [qw/func1 func2/] ], ... ],
};
Key must be lower character.
NG $Utils = { LIST => [qw/List::Util/]};
OK $Utils = { list => [qw/List::Util/]};
OK $Utils = { -list => [qw/List::Util/]};
OK $Utils = { ':list' => [qw/List::Util/]};
all
cannot be used for key.
NG $Utils = { all => [qw/List::Util/]};
NG $Utils = { -all => [qw/List::Util/]};
NG $Utils = { ':all' => [qw/List::Util/]};
Value is array ref which contained scalar or array ref.
Scalar is module name. Array ref is module name and its prefix.
$Utils = { list => ['List::Utils'] };
$Utils = { list => [['List::Utils', 'prefix_']] };
PREFIX FOR EACH MODULE
If you want to import many modules and they have same function name. You can specify prefix for each module like the following.
use base qw/Util::Any/;
our $Utils = {
list => [['List::Util' => 'lu_'], ['List::MoreUtils' => 'lmu_']]
};
In your code;
use Util::Yours qw/list/, {module_prefix => 1};
SMART RENAME FOR EACH KIND
smart_rename option renmae function name by a little smart way. For example,
our $Utils = {
utf8 => [['utf8', '',
{
is_utf8 => 'is_utf8',
upgrade => 'utf8_upgrade',
downgrade => 'downgrade',
}
]],
};
In this definition, use prefix =
1> is not good idea. If you use it:
is_utf8 => utf8_is_utf8
utf8_upgrade => utf8_utf8_upgrade
downgrade => utf8_downgrade
That's too bad. If you use smart_rename =
1> instead:
is_utf8 => is_utf8
utf8_upgrade => utf8_upgrade
downgrade => utf8_downgrade
rename rule is represented in _create_smart_rename in Util::Any.
CHANGE smart_rename BEHAVIOER
To define _create_smart_rename, you can change smart_rename behavior. _create_smart_rename get 2 argument, package name and kind of utilitiy, and should return code reference which get function name and return new name. As an example, see Util::Any's _create_smart_rename.
OTHER WAY TO EXPORT FUNCTIONS
SELECT FUNCTIONS
Util::Any auomaticaly export functions from modules' @EXPORT and @EXPORT_OK. In some cases, it is not good idea like Data::Dumper's Dumper and DumperX. Thease 2 functions are same feature.
So you can limit functions to be exported.
our $Utils = {
-debug => [
['Data::Dumper', '',
['Dumper']], # only Dumper method is exported.
],
};
or
our $Utils = {
-debug => [
['Data::Dumper', '',
{ -select => ['Dumper'] }, # only Dumper method is exported.
]
],
};
SELECT FUNCTIONS EXCEPT
Inverse of -select option. Cannot use this option with -select.
our $Utils = {
-debug => [
['Data::Dumper', '',
{ -except => ['DumperX'] }, # export functions except DumperX
]
],
};
RENAME FUNCTIONS
To rename function name, use this option with -select or -exception, this definition is prior to them.
In the following example, 'min' is not in -select list, but can be exported.
our $Utils = {
-list => [
[
'List::Util', '',
{
'first' => 'list_first', # first as list_first
'sum' => 'lsum', # sum as lsum
'min' => 'lmin', # min as lmin
-select => ['first', 'sum', 'shuffle'],
}
]
],
};
USE Sub::Exporter's GENERATOR WAY
It's somewhat complecate, I just show you code.
Your utility class:
package SubExporterGenerator;
use strict;
use Util::Any -Base;
our $Utils =
{
-test => [[
'List::Util', '',
{ min => \&build_min_reformatter,}
]]
};
sub build_min_reformatter {
my ($pkg, $class, $name, @option) = @_;
no strict 'refs';
my $code = do { no strict 'refs'; \&{$class . '::' . $name}};
sub {
my @args = @_;
$code->(@args, $option[0]->{under});
}
}
Your script using your utility class:
package main;
use strict;
use lib qw(lib t/lib);
use SubExporterGenerator -test => {min => {-as => "min_under_20", under => 20}};
print min_under_20(100,25,30); # 20
print min_under_20(100,10,30); # 10
WORKING WITH EXPORTER-LIKE MODULES
CPAN has some modules to export functions. Util::Any can work with some of such modules, Exporter, Exporter::Simple, Sub::Exporter and Perl6::Export::Attrs. If you want to use other modules, please inform me or implement import method by yourself.
If you want to use module mentioned above, you have to change the way to inherit these modules.
DIFFERENCE between 'all' and '-all' or ':all'
If your utility module which inherited Util::Any has utility functions and export them by Exporter-like module, behavior of 'all' and '-all' or ':all' is a bit different.
'all' ... export all utilities defined in your package's $Utils variables.
'-all' or ':all' ... export all utilities including functions in your util module itself.
ALTERNATIVE INHERITING
Normaly, you use;
package YourUtils;
use Util::Any -Base; # or "use base qw/Util::Any/;"
But, if you want to use Exporter, Exporter::Simple or Perl6::Export::Attrs. write as the following, instead.
# if you want to use Exporter
use Util::Any -Exporter;
# if you want to use Exporter::Simple
use Util::Any -ExporterSimple;
# if you want to use Sub::Exporter
use Util::Any -SubExporter;
# if you want to use Perl6::Export::Attrs
use Util::Any -Perl6ExportAttrs;
That's all. Note that don't use base the above modules in your utility module.
There is one notice to use Sub::Exporter.
Sub::Exporter::setup_exporter
({
as => 'do_import', # name is important
exports => [...],
groups => { ... },
});
You must pass "as" option to setup_exporter and its value must be "do_import". If you want to change this name, do the following.
Sub::Exporter::setup_exporter
({
as => $YourUtils::SubExporterImport = '__do_import',
exports => [...],
groups => { ... },
});
EXAMPLE to USE Perl6::Export::Attrs in YOUR OWN UTIL MODULE
Perl6::Export::Attributes is not recommended in the following URL (http://www.perlfoundation.org/perl5/index.cgi?pbp_module_recommendation_commentary). So, you'd beter use other exporter module. It is left as an example.
package Util::Yours;
use Clone qw/clone/;
use Util::Any -Perl6ExportAttrs;
our $Utils = clone $Util::Any::Utils;
push @{$Utils->{list}}, qw/Your::Favorite::List::Utils/;
sub foo :Export(:DEFAULT) {
return "foo!";
}
sub bar :Export(:bar) {
return "bar!";
}
1;
IMPLEMENT IMPORT by YOURSELF
Perl6::Export::Attributes is not recommended in the following URL (http://www.perlfoundation.org/perl5/index.cgi?pbp_module_recommendation_commentary). So, you'd beter use other exporter module. It is left as an example.
You can write your own import method and BEGIN block like the following. Instead of using "use Util::Any -Perl6ExportAttrs".
package UtilPerl6ExportAttr;
use strict;
use base qw/Util::Any/;
use Clone qw/clone/;
BEGIN {
use Perl6::Export::Attrs ();
no strict 'refs';
*{__PACKAGE__ . '::MODIFY_CODE_ATTRIBUTES'} = \&Perl6::Export::Attrs::_generic_MCA;
}
our $Utils = clone $Util::Any::Utils;
$Utils->{your_list} = [
['List::Util', '', [qw(first min sum)]],
];
sub import {
my $pkg = shift;
my $caller = (caller)[0];
no strict 'refs';
eval "package $caller; $pkg" . '->Util::Any::import(@_);';
my @arg = grep !exists $Utils->{$_}, @_;
if ((@_ and @arg) or !@_) {
eval "package $caller; $pkg" . '->Perl6::Export::Attrs::_generic_import(@arg)';
}
return;
}
sub foo :Export(:DEFAULT) {
return "foo!";
}
1;
AUTHOR
Ktat, <ktat at cpan.org>
BUGS
Please report any bugs or feature requests to bug-util-any at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Util-Any. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Util::Any
You can also look for information at:
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
RT: CPAN's request tracker
Search CPAN
REPOSITORY
svn co http://svn.coderepos.org/share/lang/perl/Util-Any/trunk Util-Any
Subversion repository of Util::Any is hosted at http://coderepos.org/share/. patches and collaborators are welcome.
SEE ALSO
The following modules can work with Util::Any.
Exporter, Exporter::Simple, Sub::Exporter and Perl6::Export::Attrs.
The following is new module Util::All, based on Util::Any.
http://github.com/ktat/Util-All
ACKNOWLEDGEMENTS
COPYRIGHT & LICENSE
Copyright 2008-2009 Ktat, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.