in reply to how to export a method

PDL doesn't behave as a normal Perl object oriented module. Its quirks are described in PDL::Objects which also shows how to subclass it, which is exactly what you need.
package PDL::CV; use parent qw{ PDL }; # Tell Perl what your parent class is. sub rp { my ($self, $input) = @_; $self .= $input->reshape($self->dims); return $self } sub new { my $class = shift; return bless { PDL => shift, # See PDL::Objects for details. }, $class }

You also need to instantiate the new class:

my $d = PDL::CV->new(sequence(4,5)); my $t = pdl sequence(100,5,5); $d(0,1:4)->rp($t(0,0,1:4));

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Replies are listed 'Best First'.
Re^2: how to export a method
by etj (Priest) on Apr 28, 2022 at 15:06 UTC
    The PDL idiom was put together in the late 90s, and thanks to backward compatibility it will be difficult or impossible to change.

    That idiom can be thought of as the various modules (PDL::Primitive, PDL::Ops) being roles, and they add "methods" to the PDL namespace. The answer to the question here, in order to operate like a typical PDL module, would both export a rp function, and implement a PDL::rp function that would add a PDL-object method. Because this is a function that only makes sense with an ndarray as its input, the natural thing would be to alias the exportable function to the PDL:: version:

    package PDL::CV; use strict; use warnings; use Exporter 'import'; our @EXPORT_OK = qw(rp); *rp = \&PDL::rp; # alternative idiom, e.g. for zeroes: sub zeroes {PDL->zeroes(@_)} sub PDL::rp { my ($self, $input) = @_; $self .= $input->reshape($self->dims); $self; }
    It is very important in this specific instance to note that reshape (as seen in PDL::Core#reshape) "changes the ndarray in place", i.e. is a mutation. PDL needs a new withdims affine transformation which would do what the OP thinks reshape does. EDIT: See https://github.com/PDLPorters/pdl/issues/217 for discussion of reshape and its problems.