Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added new POD, tests and ability to pass arrayref to import which has…

… names of PDL::Util functions to be made methods
  • Loading branch information...
commit b09ea0e9cdabb8c437bcb13983e264aea08f5d9c 1 parent 87fbfb7
@jberger authored
View
31 README.pod
@@ -16,3 +16,34 @@ PDL::Util
Convenient utility functions/methods for use with PDL.
+=head1 IMPORT
+
+PDL::Util does not export anything by default. The exportable symbols come in two types, functions and methods. Methods is a strange word. When importing symbols one does not import methods. In this context a 'method' is a function which expects a piddle as its first argument.
+
+A list of symbols may be imported as usual. Tags may be imported as ':functions' and ':methods'. More interestingly if an array reference or hash reference is passed as the last item in the import list, its contents will be passed to the L<add_pdl_method> function below, in which case these functions are imported into the PDL namespace and may be used as method calls. Note, when doing this for symbols from the PDL::Util module, only those listed in the ':methods' tag may be added as a method (this is the origin of the confusing terminology). Read carefully before using this functionality.
+
+=head1 TAG :functions
+
+=head2 add_pdl_method
+
+=head1 TAG :methods
+
+Again, the FUNCTIONS provided in the method tag are not automatically methods. They simply are function which are called with a PDL object (piddle) as their first argument. This function ARE available to be imported into the PDL namespace using the L<add_pdl_method> function describe above.
+
+=head2 unroll
+
+=head2 export2d
+
+ export2d($pdl, $fh, ',');
+ -- or --
+ $pdl->export2d($fh, ',');
+
+C<export2d> may take up to 2 optional arguments, a lexical filehandle (or globref, e.g. C<\*FILE>) to write to, and a string containing a column separator. The defaults, if arguments are not given are to print to STDOUT and use a single space as the column separator. The order does not matter, the method will determine whether an argument refers to a file or not. This is done so that one may call either
+
+ $pdl->export2d($fh);
+ $pdl->export2d(',');
+
+and it will do what you mean. Unfortunately this means that unlike C<wcols> one cannot use a filename rather than a filehandle; C<export2d> would interpret the string as the column separator!
+
+The method returns the number of columns that were written.
+
View
105 lib/PDL/Util.pm
@@ -1,36 +1,75 @@
package PDL::Util;
+=head1 NAME
+
+PDL::Util
+
+=head1 SYNOPSIS
+
+ use PDL;
+ use PDL::Util 'export2d';
+
+ my $pdl = rvals(6,4);
+
+ open my $fh, '>', 'file.dat';
+ export2d($pdl, $fh);
+
+=head1 DESCRIPTION
+
+Convenient utility functions/methods for use with PDL.
+
+=cut
+
use PDL;
use Scalar::Util qw/openhandle blessed/;
use Carp;
use parent 'Exporter';
-our @EXPORT_OK = qw/
- add_pdl_method
- export2d
- unroll
-/;
our %EXPORT_TAGS = (
- all => \@EXPORT_OK,
+ functions => [qw/add_pdl_method/],
+ methods => [qw/unroll export2d/],
);
+our @EXPORT_OK;
+push @EXPORT_OK, @$_ for values %EXPORT_TAGS;
+
+$EXPORT_TAGS{'all'} = \@EXPORT_OK;
+
+=head1 IMPORT
+
+PDL::Util does not export anything by default. The exportable symbols come in two types, functions and methods. Methods is a strange word. When importing symbols one does not import methods. In this context a 'method' is a function which expects a piddle as its first argument.
+
+A list of symbols may be imported as usual. Tags may be imported as ':functions' and ':methods'. More interestingly if an array reference or hash reference is passed as the last item in the import list, its contents will be passed to the L<add_pdl_method> function below, in which case these functions are imported into the PDL namespace and may be used as method calls. Note, when doing this for symbols from the PDL::Util module, only those listed in the ':methods' tag may be added as a method (this is the origin of the confusing terminology). Read carefully before using this functionality.
+
+=cut
+
sub import {
my $package = shift;
return 1 unless @_;
my $ref_last = ref $_[-1] || '';
- my $method_spec = $ref_last eq 'HASH' ? pop : 0;
+ my $method_spec = ( grep {$ref_last eq $_} qw/HASH ARRAY/ ) ? pop : 0;
add_pdl_method($method_spec) if ($method_spec);
__PACKAGE__->export_to_level(1, $package, @_) if @_;
}
+=head1 TAG :functions
+
+=head2 add_pdl_method
+
+=cut
+
sub add_pdl_method {
my $spec = shift;
- croak 'make_pdl_method expects a hash reference as its argument'
- unless ref $spec eq 'HASH';
+ croak 'make_pdl_method expects a hash or array reference as its argument'
+ unless grep {ref $spec eq $_} qw/HASH ARRAY/;
+
+ if (ref $spec eq 'ARRAY') {
+ $spec = { map { $_ => $_ } @$spec };
+ }
foreach my $method (keys %$spec) {
my $function = $spec->{$method};
@@ -41,7 +80,7 @@ PDL already provides a method named '$method', read the PDL::Util documentation
MESSAGE
unless (ref $function && ref $function eq 'CODE') {
- if ( 1 == grep { $_ eq $function } @EXPORT_OK ) {
+ if ( 1 == grep { $_ eq $function } @{ $EXPORT_TAGS{'methods'} } ) {
no strict 'refs';
$function = \&{ 'PDL::Util::' . $function };
} else {
@@ -54,6 +93,14 @@ MESSAGE
}
}
+=head1 TAG :methods
+
+Again, the FUNCTIONS provided in the method tag are not automatically methods. They simply are function which are called with a PDL object (piddle) as their first argument. This function ARE available to be imported into the PDL namespace using the L<add_pdl_method> function describe above.
+
+=head2 unroll
+
+=cut
+
sub unroll {
my $pdl = shift;
@@ -69,6 +116,23 @@ sub unroll {
}
+=head2 export2d
+
+ export2d($pdl, $fh, ',');
+ -- or --
+ $pdl->export2d($fh, ',');
+
+C<export2d> may take up to 2 optional arguments, a lexical filehandle (or globref, e.g. C<\*FILE>) to write to, and a string containing a column separator. The defaults, if arguments are not given are to print to STDOUT and use a single space as the column separator. The order does not matter, the method will determine whether an argument refers to a file or not. This is done so that one may call either
+
+ $pdl->export2d($fh);
+ $pdl->export2d(',');
+
+and it will do what you mean. Unfortunately this means that unlike C<wcols> one cannot use a filename rather than a filehandle; C<export2d> would interpret the string as the column separator!
+
+The method returns the number of columns that were written.
+
+=cut
+
sub export2d {
my ($pdl, $fh, $sep);
$pdl = shift;
@@ -107,25 +171,4 @@ sub export2d {
1;
-__END__
-__POD__
-
-=head1 NAME
-
-PDL::Util
-
-=head1 SYNOPSIS
-
- use PDL;
- use PDL::Util 'export2d';
-
- my $pdl = rvals(6,4);
- open my $fh, '>', 'file.dat';
- export2d($pdl, $fh);
-
-=head1 DESCRIPTION
-
-Convenient utility functions/methods for use with PDL.
-
-=cut
View
6 t/10-method.t → t/10-add_method.t
@@ -1,7 +1,7 @@
use strict;
use warnings;
-use Test::More tests => 3;
+use Test::More tests => 5;
use PDL;
use_ok('PDL::Util', 'add_pdl_method');
@@ -13,6 +13,10 @@ ok($pdl->can('mymethod_ref'), "method added by code reference");
add_pdl_method({ 'mymethod_unroll' => 'unroll' });
ok($pdl->can('mymethod_unroll'), "method added by name from PDL::Util's exportable function");
+add_pdl_method(['unroll', 'export2d']);
+ok($pdl->can('unroll'), "'unroll' method added by array from PDL::Util's exportable function");
+ok($pdl->can('export2d'), "'export2d' method added by array from PDL::Util's exportable function");
+
sub method1 {
my $pdl = shift;
return 1;
View
0  t/20-import-method.t → t/20-import_method_hash.t
File renamed without changes
View
12 t/25-import_method_array.t
@@ -0,0 +1,12 @@
+use strict;
+use warnings;
+
+use PDL;
+use Test::More tests => 3;
+
+use_ok('PDL::Util', ['unroll', 'export2d']);
+
+my $pdl = zeros(5,5);
+ok($pdl->can('unroll'), "'unroll' method imported during 'use'");
+ok($pdl->can('export2d'), "'export2d' method imported during 'use'");
+

0 comments on commit b09ea0e

Please sign in to comment.
Something went wrong with that request. Please try again.