xref: /openbsd-src/gnu/usr.bin/perl/cpan/Test-Simple/lib/Test2/Util/HashBase.pm (revision 5486feefcc8cb79b19e014ab332cc5dfd05b3b33)
15759b3d2Safresh1package Test2::Util::HashBase;
25759b3d2Safresh1use strict;
35759b3d2Safresh1use warnings;
45759b3d2Safresh1
5*5486feefSafresh1our $VERSION = '1.302199';
65759b3d2Safresh1
75759b3d2Safresh1#################################################################
85759b3d2Safresh1#                                                               #
95759b3d2Safresh1#  This is a generated file! Do not modify this file directly!  #
105759b3d2Safresh1#  Use hashbase_inc.pl script to regenerate this file.          #
115759b3d2Safresh1#  The script is part of the Object::HashBase distribution.     #
125759b3d2Safresh1#  Note: You can modify the version number above this comment   #
135759b3d2Safresh1#  if needed, that is fine.                                     #
145759b3d2Safresh1#                                                               #
155759b3d2Safresh1#################################################################
165759b3d2Safresh1
175759b3d2Safresh1{
185759b3d2Safresh1    no warnings 'once';
19de8cc8edSafresh1    $Test2::Util::HashBase::HB_VERSION = '0.009';
205759b3d2Safresh1    *Test2::Util::HashBase::ATTR_SUBS = \%Object::HashBase::ATTR_SUBS;
215759b3d2Safresh1    *Test2::Util::HashBase::ATTR_LIST = \%Object::HashBase::ATTR_LIST;
225759b3d2Safresh1    *Test2::Util::HashBase::VERSION   = \%Object::HashBase::VERSION;
235759b3d2Safresh1    *Test2::Util::HashBase::CAN_CACHE = \%Object::HashBase::CAN_CACHE;
245759b3d2Safresh1}
255759b3d2Safresh1
265759b3d2Safresh1
275759b3d2Safresh1require Carp;
285759b3d2Safresh1{
295759b3d2Safresh1    no warnings 'once';
305759b3d2Safresh1    $Carp::Internal{+__PACKAGE__} = 1;
315759b3d2Safresh1}
325759b3d2Safresh1
335759b3d2Safresh1BEGIN {
345759b3d2Safresh1    # these are not strictly equivalent, but for out use we don't care
355759b3d2Safresh1    # about order
365759b3d2Safresh1    *_isa = ($] >= 5.010 && require mro) ? \&mro::get_linear_isa : sub {
375759b3d2Safresh1        no strict 'refs';
385759b3d2Safresh1        my @packages = ($_[0]);
395759b3d2Safresh1        my %seen;
405759b3d2Safresh1        for my $package (@packages) {
415759b3d2Safresh1            push @packages, grep !$seen{$_}++, @{"$package\::ISA"};
425759b3d2Safresh1        }
435759b3d2Safresh1        return \@packages;
445759b3d2Safresh1    }
455759b3d2Safresh1}
465759b3d2Safresh1
47de8cc8edSafresh1my %SPEC = (
48de8cc8edSafresh1    '^' => {reader => 1, writer => 0, dep_writer => 1, read_only => 0, strip => 1},
49de8cc8edSafresh1    '-' => {reader => 1, writer => 0, dep_writer => 0, read_only => 1, strip => 1},
50de8cc8edSafresh1    '>' => {reader => 0, writer => 1, dep_writer => 0, read_only => 0, strip => 1},
51de8cc8edSafresh1    '<' => {reader => 1, writer => 0, dep_writer => 0, read_only => 0, strip => 1},
52de8cc8edSafresh1    '+' => {reader => 0, writer => 0, dep_writer => 0, read_only => 0, strip => 1},
535759b3d2Safresh1);
545759b3d2Safresh1
555759b3d2Safresh1sub import {
565759b3d2Safresh1    my $class = shift;
575759b3d2Safresh1    my $into  = caller;
585759b3d2Safresh1
595759b3d2Safresh1    # Make sure we list the OLDEST version used to create this class.
605759b3d2Safresh1    my $ver = $Test2::Util::HashBase::HB_VERSION || $Test2::Util::HashBase::VERSION;
615759b3d2Safresh1    $Test2::Util::HashBase::VERSION{$into} = $ver if !$Test2::Util::HashBase::VERSION{$into} || $Test2::Util::HashBase::VERSION{$into} > $ver;
625759b3d2Safresh1
635759b3d2Safresh1    my $isa = _isa($into);
645759b3d2Safresh1    my $attr_list = $Test2::Util::HashBase::ATTR_LIST{$into} ||= [];
655759b3d2Safresh1    my $attr_subs = $Test2::Util::HashBase::ATTR_SUBS{$into} ||= {};
665759b3d2Safresh1
675759b3d2Safresh1    my %subs = (
685759b3d2Safresh1        ($into->can('new') ? () : (new => \&_new)),
695759b3d2Safresh1        (map %{$Test2::Util::HashBase::ATTR_SUBS{$_} || {}}, @{$isa}[1 .. $#$isa]),
705759b3d2Safresh1        (
715759b3d2Safresh1            map {
725759b3d2Safresh1                my $p = substr($_, 0, 1);
735759b3d2Safresh1                my $x = $_;
74de8cc8edSafresh1
75de8cc8edSafresh1                my $spec = $SPEC{$p} || {reader => 1, writer => 1};
76de8cc8edSafresh1
77de8cc8edSafresh1                substr($x, 0, 1) = '' if $spec->{strip};
785759b3d2Safresh1                push @$attr_list => $x;
795759b3d2Safresh1                my ($sub, $attr) = (uc $x, $x);
80de8cc8edSafresh1
81de8cc8edSafresh1                $attr_subs->{$sub} = sub() { $attr };
82de8cc8edSafresh1                my %out = ($sub => $attr_subs->{$sub});
83de8cc8edSafresh1
84de8cc8edSafresh1                $out{$attr}       = sub { $_[0]->{$attr} }                                                  if $spec->{reader};
85de8cc8edSafresh1                $out{"set_$attr"} = sub { $_[0]->{$attr} = $_[1] }                                          if $spec->{writer};
86de8cc8edSafresh1                $out{"set_$attr"} = sub { Carp::croak("'$attr' is read-only") }                             if $spec->{read_only};
87de8cc8edSafresh1                $out{"set_$attr"} = sub { Carp::carp("set_$attr() is deprecated"); $_[0]->{$attr} = $_[1] } if $spec->{dep_writer};
88de8cc8edSafresh1
89de8cc8edSafresh1                %out;
905759b3d2Safresh1            } @_
915759b3d2Safresh1        ),
925759b3d2Safresh1    );
935759b3d2Safresh1
945759b3d2Safresh1    no strict 'refs';
955759b3d2Safresh1    *{"$into\::$_"} = $subs{$_} for keys %subs;
965759b3d2Safresh1}
975759b3d2Safresh1
985759b3d2Safresh1sub attr_list {
995759b3d2Safresh1    my $class = shift;
1005759b3d2Safresh1
1015759b3d2Safresh1    my $isa = _isa($class);
1025759b3d2Safresh1
1035759b3d2Safresh1    my %seen;
1045759b3d2Safresh1    my @list = grep { !$seen{$_}++ } map {
1055759b3d2Safresh1        my @out;
1065759b3d2Safresh1
1075759b3d2Safresh1        if (0.004 > ($Test2::Util::HashBase::VERSION{$_} || 0)) {
1085759b3d2Safresh1            Carp::carp("$_ uses an inlined version of Test2::Util::HashBase too old to support attr_list()");
1095759b3d2Safresh1        }
1105759b3d2Safresh1        else {
1115759b3d2Safresh1            my $list = $Test2::Util::HashBase::ATTR_LIST{$_};
1125759b3d2Safresh1            @out = $list ? @$list : ()
1135759b3d2Safresh1        }
1145759b3d2Safresh1
1155759b3d2Safresh1        @out;
1165759b3d2Safresh1    } reverse @$isa;
1175759b3d2Safresh1
1185759b3d2Safresh1    return @list;
1195759b3d2Safresh1}
1205759b3d2Safresh1
1215759b3d2Safresh1sub _new {
1225759b3d2Safresh1    my $class = shift;
1235759b3d2Safresh1
1245759b3d2Safresh1    my $self;
1255759b3d2Safresh1
1265759b3d2Safresh1    if (@_ == 1) {
1275759b3d2Safresh1        my $arg = shift;
1285759b3d2Safresh1        my $type = ref($arg);
1295759b3d2Safresh1
1305759b3d2Safresh1        if ($type eq 'HASH') {
1315759b3d2Safresh1            $self = bless({%$arg}, $class)
1325759b3d2Safresh1        }
1335759b3d2Safresh1        else {
1345759b3d2Safresh1            Carp::croak("Not sure what to do with '$type' in $class constructor")
1355759b3d2Safresh1                unless $type eq 'ARRAY';
1365759b3d2Safresh1
1375759b3d2Safresh1            my %proto;
1385759b3d2Safresh1            my @attributes = attr_list($class);
1395759b3d2Safresh1            while (@$arg) {
1405759b3d2Safresh1                my $val = shift @$arg;
1415759b3d2Safresh1                my $key = shift @attributes or Carp::croak("Too many arguments for $class constructor");
1425759b3d2Safresh1                $proto{$key} = $val;
1435759b3d2Safresh1            }
1445759b3d2Safresh1
1455759b3d2Safresh1            $self = bless(\%proto, $class);
1465759b3d2Safresh1        }
1475759b3d2Safresh1    }
1485759b3d2Safresh1    else {
1495759b3d2Safresh1        $self = bless({@_}, $class);
1505759b3d2Safresh1    }
1515759b3d2Safresh1
1525759b3d2Safresh1    $Test2::Util::HashBase::CAN_CACHE{$class} = $self->can('init')
1535759b3d2Safresh1        unless exists $Test2::Util::HashBase::CAN_CACHE{$class};
1545759b3d2Safresh1
1555759b3d2Safresh1    $self->init if $Test2::Util::HashBase::CAN_CACHE{$class};
1565759b3d2Safresh1
1575759b3d2Safresh1    $self;
1585759b3d2Safresh1}
1595759b3d2Safresh1
1605759b3d2Safresh11;
1615759b3d2Safresh1
1625759b3d2Safresh1__END__
1635759b3d2Safresh1
1645759b3d2Safresh1=pod
1655759b3d2Safresh1
1665759b3d2Safresh1=encoding UTF-8
1675759b3d2Safresh1
1685759b3d2Safresh1=head1 NAME
1695759b3d2Safresh1
1705759b3d2Safresh1Test2::Util::HashBase - Build hash based classes.
1715759b3d2Safresh1
1725759b3d2Safresh1=head1 SYNOPSIS
1735759b3d2Safresh1
1745759b3d2Safresh1A class:
1755759b3d2Safresh1
1765759b3d2Safresh1    package My::Class;
1775759b3d2Safresh1    use strict;
1785759b3d2Safresh1    use warnings;
1795759b3d2Safresh1
1805759b3d2Safresh1    # Generate 3 accessors
181de8cc8edSafresh1    use Test2::Util::HashBase qw/foo -bar ^baz <bat >ban +boo/;
1825759b3d2Safresh1
1835759b3d2Safresh1    # Chance to initialize defaults
1845759b3d2Safresh1    sub init {
1855759b3d2Safresh1        my $self = shift;    # No other args
1865759b3d2Safresh1        $self->{+FOO} ||= "foo";
1875759b3d2Safresh1        $self->{+BAR} ||= "bar";
1885759b3d2Safresh1        $self->{+BAZ} ||= "baz";
189de8cc8edSafresh1        $self->{+BAT} ||= "bat";
190de8cc8edSafresh1        $self->{+BAN} ||= "ban";
191de8cc8edSafresh1        $self->{+BOO} ||= "boo";
1925759b3d2Safresh1    }
1935759b3d2Safresh1
1945759b3d2Safresh1    sub print {
195de8cc8edSafresh1        print join ", " => map { $self->{$_} } FOO, BAR, BAZ, BAT, BAN, BOO;
1965759b3d2Safresh1    }
1975759b3d2Safresh1
1985759b3d2Safresh1Subclass it
1995759b3d2Safresh1
2005759b3d2Safresh1    package My::Subclass;
2015759b3d2Safresh1    use strict;
2025759b3d2Safresh1    use warnings;
2035759b3d2Safresh1
2045759b3d2Safresh1    # Note, you should subclass before loading HashBase.
2055759b3d2Safresh1    use base 'My::Class';
206de8cc8edSafresh1    use Test2::Util::HashBase qw/bub/;
2075759b3d2Safresh1
2085759b3d2Safresh1    sub init {
2095759b3d2Safresh1        my $self = shift;
2105759b3d2Safresh1
2115759b3d2Safresh1        # We get the constants from the base class for free.
2125759b3d2Safresh1        $self->{+FOO} ||= 'SubFoo';
213de8cc8edSafresh1        $self->{+BUB} ||= 'bub';
2145759b3d2Safresh1
2155759b3d2Safresh1        $self->SUPER::init();
2165759b3d2Safresh1    }
2175759b3d2Safresh1
2185759b3d2Safresh1use it:
2195759b3d2Safresh1
2205759b3d2Safresh1    package main;
2215759b3d2Safresh1    use strict;
2225759b3d2Safresh1    use warnings;
2235759b3d2Safresh1    use My::Class;
2245759b3d2Safresh1
2255759b3d2Safresh1    # These are all functionally identical
2265759b3d2Safresh1    my $one   = My::Class->new(foo => 'MyFoo', bar => 'MyBar');
2275759b3d2Safresh1    my $two   = My::Class->new({foo => 'MyFoo', bar => 'MyBar'});
2285759b3d2Safresh1    my $three = My::Class->new(['MyFoo', 'MyBar']);
2295759b3d2Safresh1
230de8cc8edSafresh1    # Readers!
2315759b3d2Safresh1    my $foo = $one->foo;    # 'MyFoo'
2325759b3d2Safresh1    my $bar = $one->bar;    # 'MyBar'
2335759b3d2Safresh1    my $baz = $one->baz;    # Defaulted to: 'baz'
234de8cc8edSafresh1    my $bat = $one->bat;    # Defaulted to: 'bat'
235de8cc8edSafresh1    # '>ban' means setter only, no reader
236de8cc8edSafresh1    # '+boo' means no setter or reader, just the BOO constant
2375759b3d2Safresh1
2385759b3d2Safresh1    # Setters!
2395759b3d2Safresh1    $one->set_foo('A Foo');
2405759b3d2Safresh1
2415759b3d2Safresh1    #'-bar' means read-only, so the setter will throw an exception (but is defined).
2425759b3d2Safresh1    $one->set_bar('A bar');
2435759b3d2Safresh1
2445759b3d2Safresh1    # '^baz' means deprecated setter, this will warn about the setter being
2455759b3d2Safresh1    # deprecated.
2465759b3d2Safresh1    $one->set_baz('A Baz');
2475759b3d2Safresh1
248de8cc8edSafresh1    # '<bat' means no setter defined at all
249de8cc8edSafresh1    # '+boo' means no setter or reader, just the BOO constant
250de8cc8edSafresh1
2515759b3d2Safresh1    $one->{+FOO} = 'xxx';
2525759b3d2Safresh1
2535759b3d2Safresh1=head1 DESCRIPTION
2545759b3d2Safresh1
2555759b3d2Safresh1This package is used to generate classes based on hashrefs. Using this class
2565759b3d2Safresh1will give you a C<new()> method, as well as generating accessors you request.
2575759b3d2Safresh1Generated accessors will be getters, C<set_ACCESSOR> setters will also be
2585759b3d2Safresh1generated for you. You also get constants for each accessor (all caps) which
2595759b3d2Safresh1return the key into the hash for that accessor. Single inheritance is also
2605759b3d2Safresh1supported.
2615759b3d2Safresh1
2625759b3d2Safresh1=head1 THIS IS A BUNDLED COPY OF HASHBASE
2635759b3d2Safresh1
2645759b3d2Safresh1This is a bundled copy of L<Object::HashBase>. This file was generated using
2655759b3d2Safresh1the
2665759b3d2Safresh1C</home/exodist/perl5/perlbrew/perls/main/bin/hashbase_inc.pl>
2675759b3d2Safresh1script.
2685759b3d2Safresh1
2695759b3d2Safresh1=head1 METHODS
2705759b3d2Safresh1
2715759b3d2Safresh1=head2 PROVIDED BY HASH BASE
2725759b3d2Safresh1
2735759b3d2Safresh1=over 4
2745759b3d2Safresh1
2755759b3d2Safresh1=item $it = $class->new(%PAIRS)
2765759b3d2Safresh1
2775759b3d2Safresh1=item $it = $class->new(\%PAIRS)
2785759b3d2Safresh1
2795759b3d2Safresh1=item $it = $class->new(\@ORDERED_VALUES)
2805759b3d2Safresh1
2815759b3d2Safresh1Create a new instance.
2825759b3d2Safresh1
2835759b3d2Safresh1HashBase will not export C<new()> if there is already a C<new()> method in your
2845759b3d2Safresh1packages inheritance chain.
2855759b3d2Safresh1
2865759b3d2Safresh1B<If you do not want this method you can define your own> you just have to
2875759b3d2Safresh1declare it before loading L<Test2::Util::HashBase>.
2885759b3d2Safresh1
2895759b3d2Safresh1    package My::Package;
2905759b3d2Safresh1
2915759b3d2Safresh1    # predeclare new() so that HashBase does not give us one.
2925759b3d2Safresh1    sub new;
2935759b3d2Safresh1
2945759b3d2Safresh1    use Test2::Util::HashBase qw/foo bar baz/;
2955759b3d2Safresh1
2965759b3d2Safresh1    # Now we define our own new method.
2975759b3d2Safresh1    sub new { ... }
2985759b3d2Safresh1
2995759b3d2Safresh1This makes it so that HashBase sees that you have your own C<new()> method.
3005759b3d2Safresh1Alternatively you can define the method before loading HashBase instead of just
3015759b3d2Safresh1declaring it, but that scatters your use statements.
3025759b3d2Safresh1
3035759b3d2Safresh1The most common way to create an object is to pass in key/value pairs where
3045759b3d2Safresh1each key is an attribute and each value is what you want assigned to that
3055759b3d2Safresh1attribute. No checking is done to verify the attributes or values are valid,
3065759b3d2Safresh1you may do that in C<init()> if desired.
3075759b3d2Safresh1
3085759b3d2Safresh1If you would like, you can pass in a hashref instead of pairs. When you do so
3095759b3d2Safresh1the hashref will be copied, and the copy will be returned blessed as an object.
3105759b3d2Safresh1There is no way to ask HashBase to bless a specific hashref.
3115759b3d2Safresh1
3125759b3d2Safresh1In some cases an object may only have 1 or 2 attributes, in which case a
3135759b3d2Safresh1hashref may be too verbose for your liking. In these cases you can pass in an
3145759b3d2Safresh1arrayref with only values. The values will be assigned to attributes in the
3155759b3d2Safresh1order the attributes were listed. When there is inheritance involved the
3165759b3d2Safresh1attributes from parent classes will come before subclasses.
3175759b3d2Safresh1
3185759b3d2Safresh1=back
3195759b3d2Safresh1
3205759b3d2Safresh1=head2 HOOKS
3215759b3d2Safresh1
3225759b3d2Safresh1=over 4
3235759b3d2Safresh1
3245759b3d2Safresh1=item $self->init()
3255759b3d2Safresh1
3265759b3d2Safresh1This gives you the chance to set some default values to your fields. The only
3275759b3d2Safresh1argument is C<$self> with its indexes already set from the constructor.
3285759b3d2Safresh1
3295759b3d2Safresh1B<Note:> Test2::Util::HashBase checks for an init using C<< $class->can('init') >>
3305759b3d2Safresh1during construction. It DOES NOT call C<can()> on the created object. Also note
3315759b3d2Safresh1that the result of the check is cached, it is only ever checked once, the first
3325759b3d2Safresh1time an instance of your class is created. This means that adding an C<init()>
3335759b3d2Safresh1method AFTER the first construction will result in it being ignored.
3345759b3d2Safresh1
3355759b3d2Safresh1=back
3365759b3d2Safresh1
3375759b3d2Safresh1=head1 ACCESSORS
3385759b3d2Safresh1
3395759b3d2Safresh1=head2 READ/WRITE
3405759b3d2Safresh1
3415759b3d2Safresh1To generate accessors you list them when using the module:
3425759b3d2Safresh1
3435759b3d2Safresh1    use Test2::Util::HashBase qw/foo/;
3445759b3d2Safresh1
3455759b3d2Safresh1This will generate the following subs in your namespace:
3465759b3d2Safresh1
3475759b3d2Safresh1=over 4
3485759b3d2Safresh1
3495759b3d2Safresh1=item foo()
3505759b3d2Safresh1
3515759b3d2Safresh1Getter, used to get the value of the C<foo> field.
3525759b3d2Safresh1
3535759b3d2Safresh1=item set_foo()
3545759b3d2Safresh1
3555759b3d2Safresh1Setter, used to set the value of the C<foo> field.
3565759b3d2Safresh1
3575759b3d2Safresh1=item FOO()
3585759b3d2Safresh1
3595759b3d2Safresh1Constant, returns the field C<foo>'s key into the class hashref. Subclasses will
3605759b3d2Safresh1also get this function as a constant, not simply a method, that means it is
3615759b3d2Safresh1copied into the subclass namespace.
3625759b3d2Safresh1
3635759b3d2Safresh1The main reason for using these constants is to help avoid spelling mistakes
3645759b3d2Safresh1and similar typos. It will not help you if you forget to prefix the '+' though.
3655759b3d2Safresh1
3665759b3d2Safresh1=back
3675759b3d2Safresh1
3685759b3d2Safresh1=head2 READ ONLY
3695759b3d2Safresh1
3705759b3d2Safresh1    use Test2::Util::HashBase qw/-foo/;
3715759b3d2Safresh1
3725759b3d2Safresh1=over 4
3735759b3d2Safresh1
3745759b3d2Safresh1=item set_foo()
3755759b3d2Safresh1
3765759b3d2Safresh1Throws an exception telling you the attribute is read-only. This is exported to
3775759b3d2Safresh1override any active setters for the attribute in a parent class.
3785759b3d2Safresh1
3795759b3d2Safresh1=back
3805759b3d2Safresh1
3815759b3d2Safresh1=head2 DEPRECATED SETTER
3825759b3d2Safresh1
3835759b3d2Safresh1    use Test2::Util::HashBase qw/^foo/;
3845759b3d2Safresh1
3855759b3d2Safresh1=over 4
3865759b3d2Safresh1
3875759b3d2Safresh1=item set_foo()
3885759b3d2Safresh1
3895759b3d2Safresh1This will set the value, but it will also warn you that the method is
3905759b3d2Safresh1deprecated.
3915759b3d2Safresh1
3925759b3d2Safresh1=back
3935759b3d2Safresh1
394de8cc8edSafresh1=head2 NO SETTER
395de8cc8edSafresh1
396de8cc8edSafresh1    use Test2::Util::HashBase qw/<foo/;
397de8cc8edSafresh1
398de8cc8edSafresh1Only gives you a reader, no C<set_foo> method is defined at all.
399de8cc8edSafresh1
400de8cc8edSafresh1=head2 NO READER
401de8cc8edSafresh1
402de8cc8edSafresh1    use Test2::Util::HashBase qw/>foo/;
403de8cc8edSafresh1
404de8cc8edSafresh1Only gives you a write (C<set_foo>), no C<foo> method is defined at all.
405de8cc8edSafresh1
406de8cc8edSafresh1=head2 CONSTANT ONLY
407de8cc8edSafresh1
408de8cc8edSafresh1    use Test2::Util::HashBase qw/+foo/;
409de8cc8edSafresh1
410de8cc8edSafresh1This does not create any methods for you, it just adds the C<FOO> constant.
411de8cc8edSafresh1
4125759b3d2Safresh1=head1 SUBCLASSING
4135759b3d2Safresh1
4145759b3d2Safresh1You can subclass an existing HashBase class.
4155759b3d2Safresh1
4165759b3d2Safresh1    use base 'Another::HashBase::Class';
4175759b3d2Safresh1    use Test2::Util::HashBase qw/foo bar baz/;
4185759b3d2Safresh1
4195759b3d2Safresh1The base class is added to C<@ISA> for you, and all constants from base classes
4205759b3d2Safresh1are added to subclasses automatically.
4215759b3d2Safresh1
4225759b3d2Safresh1=head1 GETTING A LIST OF ATTRIBUTES FOR A CLASS
4235759b3d2Safresh1
4245759b3d2Safresh1Test2::Util::HashBase provides a function for retrieving a list of attributes for an
4255759b3d2Safresh1Test2::Util::HashBase class.
4265759b3d2Safresh1
4275759b3d2Safresh1=over 4
4285759b3d2Safresh1
4295759b3d2Safresh1=item @list = Test2::Util::HashBase::attr_list($class)
4305759b3d2Safresh1
4315759b3d2Safresh1=item @list = $class->Test2::Util::HashBase::attr_list()
4325759b3d2Safresh1
4335759b3d2Safresh1Either form above will work. This will return a list of attributes defined on
4345759b3d2Safresh1the object. This list is returned in the attribute definition order, parent
4355759b3d2Safresh1class attributes are listed before subclass attributes. Duplicate attributes
4365759b3d2Safresh1will be removed before the list is returned.
4375759b3d2Safresh1
4385759b3d2Safresh1B<Note:> This list is used in the C<< $class->new(\@ARRAY) >> constructor to
4395759b3d2Safresh1determine the attribute to which each value will be paired.
4405759b3d2Safresh1
4415759b3d2Safresh1=back
4425759b3d2Safresh1
4435759b3d2Safresh1=head1 SOURCE
4445759b3d2Safresh1
4455759b3d2Safresh1The source code repository for HashBase can be found at
446*5486feefSafresh1L<https://github.com/Test-More/HashBase/>.
4475759b3d2Safresh1
4485759b3d2Safresh1=head1 MAINTAINERS
4495759b3d2Safresh1
4505759b3d2Safresh1=over 4
4515759b3d2Safresh1
4525759b3d2Safresh1=item Chad Granum E<lt>exodist@cpan.orgE<gt>
4535759b3d2Safresh1
4545759b3d2Safresh1=back
4555759b3d2Safresh1
4565759b3d2Safresh1=head1 AUTHORS
4575759b3d2Safresh1
4585759b3d2Safresh1=over 4
4595759b3d2Safresh1
4605759b3d2Safresh1=item Chad Granum E<lt>exodist@cpan.orgE<gt>
4615759b3d2Safresh1
4625759b3d2Safresh1=back
4635759b3d2Safresh1
4645759b3d2Safresh1=head1 COPYRIGHT
4655759b3d2Safresh1
466de8cc8edSafresh1Copyright 2017 Chad Granum E<lt>exodist@cpan.orgE<gt>.
4675759b3d2Safresh1
4685759b3d2Safresh1This program is free software; you can redistribute it and/or
4695759b3d2Safresh1modify it under the same terms as Perl itself.
4705759b3d2Safresh1
471*5486feefSafresh1See L<https://dev.perl.org/licenses/>
4725759b3d2Safresh1
4735759b3d2Safresh1=cut
474