Skip Menu |

This queue is for tickets about the Set-Equivalence CPAN distribution.

Report information
The Basics
Id: 99298
Status: open
Priority: 0/
Queue: Set-Equivalence

People
Owner: perl [...] toby.ink
Requestors: SJM [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: (no value)



Subject: Subclassing Set::Equivalence
I'd like to be able to subclass Set::Equivalence, but the creation of new sets via set arithmetic can't really be controlled. I'd be nice to somehow control the $maker coderef returned by _args().
On 2014-10-03T21:10:47+01:00, SJM wrote: Show quoted text
> I'd like to be able to subclass Set::Equivalence, but the creation of > new sets via set arithmetic can't really be controlled. I'd be nice > to somehow control the $maker coderef returned by _args().
It is somewhat intentional that _args() cannot be overridden. If you've got two Set::Equivalence subclasses, there's a danger they'd both try to override _args() which might lead to weird behaviour when $maker is being used to combine two sets (like in the union and intersection methods). However, _args() has a bug on line 265 - it should be checking $_[$_]->isa(__PACKAGE__). Looking at the sub again, there's another few changes that probably ought to be made to it as well. What extra functionality would you like to be able to squeeze into $maker? I may be able to provide some hooks you can use.
I think the main things are being able to control what arguments are passed to new() and as a slightly more esoteric case, maybe control how to check if the sets being acted upon are compatible. Off the top of my head, maybe something along the lines of: sub _args { my $n = shift; my ($class, @args); if (ref $_[0]) { $class = ref($_[0]); @args = $_[0]->_maker_args; } else { $class = shift; } for (0 .. $n-1) { $_[0]->_valid_set($_[$_]) or croak("expected $class; got $_[$_]"); } return ( sub { my @members = @_; $class->new(members => \@members, @args); }, @_ ); } sub _valid_set { my $self = shift; my $set = shift; my $class = ref($_[0]); return blessed($set) && $set->isa($class); } sub _maker_args { my $self = shift; my (@eq, @tc); @eq = (equivalence_relation => $self->equivalence_relation); @tc = (type_constraint => $self->type_constraint) if $self->type_constraint; return (@eq, @tc); }