Commit 040a7a40 authored by Felix Lechner's avatar Felix Lechner

To allow serialization of Lintian::CollScript, pass package names as strings instead of coderefs

The coderef prevents the class CollScript from being serialized. That
makes it much less convenient or even impossible to use it, for
example in IO::Async::Function with its multi process features.

This change makes the class CollScript more versatile. Stores the
module name as a string instead of a coderef.

One can still use the class inside a IO::Async::Function without this
change by "closing" on it, i.e.  just using it as a local variable,
but that also means that the function must be defined in the loop.

Also, uses '->can' from UNIVERSAL to check for the presence of the
instance method 'collect', which is cleaner and more elegant. That
idea was based on this exchange with mst on #perl-help:

11:37 <@mst> if ("Lintian::coll::$ppkg"->can('collect')) { would be nicer
11:38 <@mst> and in the child you can call "Lintian::coll::$ppkg"->collect(...)
11:39 <@mst> and then you get rid of a 'no strict' *and* the bug :)

Gbp-Dch: ignore
parent 16f374f9
......@@ -75,7 +75,7 @@ sub new {
'type-table' => {},
'priority' => $header->{'priority'} // 8192,
'interface' => $header->{'interface'}//'exec',
'_collect_sub' => undef,
'collector_class' => undef,
};
$self->{'script_path'} = dirname($file) . '/' . $self->{'name'};
for my $t (split /\s*,\s*/o, $self->{'type'}) {
......@@ -223,8 +223,10 @@ sub collect {
my ($self, $pkg_name, $task, $dir) = @_;
my $iface = $self->interface;
if ($iface eq 'perl-coll') {
my $collector = $self->{'_collect_sub'};
$collector->($pkg_name, $task, $dir);
my $cs_path = $self->script_path;
require $cs_path;
my $collector = $self->{'collector_class'};
$collector->can('collect')->($pkg_name, $task, $dir);
} elsif ($iface eq 'exec') {
system($self->script_path, $pkg_name, $task, $dir) == 0
or die 'Collection ' . $self->name . " for $pkg_name failed\n";
......@@ -247,13 +249,13 @@ sub _load_collector {
require $cs_path;
{
no strict 'refs';
$collector = \&{'Lintian::coll::' . $ppkg . '::collect'}
if defined &{'Lintian::coll::' . $ppkg . '::collect'};
my $candidate = "Lintian::coll::$ppkg";
$collector = $candidate
if $candidate->can('collect');
}
internal_error($self->name . ' does not have a collect function')
unless defined $collector;
$self->{'_collect_sub'} = $collector;
$self->{'collector_class'} = $collector;
return;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment