# # Copyright (c) 2019 Christian Jaeger, copying@christianjaeger.ch # # This is free software, offered under either the same terms as perl 5 # or the terms of the Artistic License version 2 or the terms of the # MIT License (Expat version). See the file COPYING.md that came # bundled with this file. # =head1 NAME FP::Struct::Equal -- automatic Equal protocol implementation =head1 SYNOPSIS package FP_Struct_Equal_Example::Foo { use FP::Struct ["a","b"], 'FP::Struct::Equal'; _END_ } FP_Struct_Equal_Example::Foo::constructors->import; use FP::Equal; ok equal(Foo(1, [1+1, 3]), Foo(1, [2, 3])); ok not equal(Foo(1, 1+1), Foo(1, [3])); =head1 DESCRIPTION This class, when listed as a superclass of an L, automatically implements the L protocol (i.e. generates an `FP_Equal_equal` method that uses inspection specific to FP::Struct classes to get to know the public field values of the object it is being called on, and reconstructs a constructor call based on this information.) This will be the right thing for the typical `FP::Struct` based class that don't have or mutate hidden fields or want to exclude some fields from equality tests. =head1 SEE ALSO Creates implementations for: L L =head1 NOTE This is alpha software! Read the status section in the package README or on the L. =cut package FP::Struct::Equal; use strict; use warnings; use warnings FATAL => 'uninitialized'; use base 'FP::Abstract::Equal'; use FP::Equal (); sub FP_Equal_equal { my ($self, $b) = @_; my $class = ref($self); length $class or die "FP_Show_show called on non-object: $self"; my $fieldnames = do { no strict 'refs'; \@{"${class}::__Struct__fields"} }; # XX is all_fields slow, probably? Optim? for (FP::Struct::all_fields([$class])) { my $fieldname = FP::Struct::field_name($_); FP::Equal::equal($self->$fieldname, $b->$fieldname) or return 0 } 1 } 1