1 package Test2::Util::HashBase;
5 our $VERSION = '1.302022';
9 $Carp::Internal{+__PACKAGE__} = 1;
14 # these are not strictly equivalent, but for out use we don't care
16 *_isa = ($] >= 5.010 && require mro) ? \&mro::get_linear_isa : sub {
18 my @packages = ($_[0]);
20 for my $package (@packages) {
21 push @packages, grep !$seen{$_}++, @{"$package\::ISA"};
31 my $isa = _isa($into);
32 my $attr_subs = $ATTR_SUBS{$into} ||= {};
34 ($into->can('new') ? () : (new => \&_new)),
35 (map %{ $ATTR_SUBS{$_}||{} }, @{$isa}[1 .. $#$isa]),
37 my ($sub, $attr) = (uc $_, $_);
38 $sub => ($attr_subs->{$sub} = sub() { $attr }),
39 $attr => sub { $_[0]->{$attr} },
40 "set_$attr" => sub { $_[0]->{$attr} = $_[1] },
45 *{"$into\::$_"} = $subs{$_} for keys %subs;
49 my ($class, %params) = @_;
50 my $self = bless \%params, $class;
51 $self->init if $self->can('init');
65 Test2::Util::HashBase - Base class for classes that use a hashref
76 # Generate 3 accessors
77 use Test2::Util::HashBase qw/foo bar baz/;
79 # Chance to initialize defaults
81 my $self = shift; # No other args
82 $self->{+FOO} ||= "foo";
83 $self->{+BAR} ||= "bar";
84 $self->{+BAZ} ||= "baz";
88 print join ", " => map { $self->{$_} } FOO, BAR, BAZ;
97 # Note, you should subclass before loading HashBase.
99 use Test2::Util::HashBase qw/bat/;
104 # We get the constants from the base class for free.
105 $self->{+FOO} ||= 'SubFoo';
106 $self->{+BAT} || = 'bat';
108 $self->SUPER::init();
118 my $one = My::Class->new(foo => 'MyFoo', bar => 'MyBar');
121 my $foo = $one->foo; # 'MyFoo'
122 my $bar = $one->bar; # 'MyBar'
123 my $baz = $one->baz; # Defaulted to: 'baz'
126 $one->set_foo('A Foo');
127 $one->set_bar('A Bar');
128 $one->set_baz('A Baz');
130 $one->{+FOO} = 'xxx';
134 This package is used to generate classes based on hashrefs. Using this class
135 will give you a C<new()> method, as well as generating accessors you request.
136 Generated accessors will be getters, C<set_ACCESSOR> setters will also be
137 generated for you. You also get constants for each accessor (all caps) which
138 return the key into the hash for that accessor. Single inheritance is also
143 =head2 PROVIDED BY HASH BASE
147 =item $it = $class->new(@VALUES)
149 Create a new instance using key/value pairs.
151 HashBase will not export C<new()> if there is already a C<new()> method in your
152 packages inheritance chain.
154 B<If you do not want this method you can define your own> you just have to
155 declare it before loading L<Test2::Util::HashBase>.
159 # predeclare new() so that HashBase does not give us one.
162 use Test2::Util::HashBase qw/foo bar baz/;
164 # Now we define our own new method.
167 This makes it so that HashBase sees that you have your own C<new()> method.
168 Alternatively you can define the method before loading HashBase instead of just
169 declaring it, but that scatters your use statements.
179 This gives you the chance to set some default values to your fields. The only
180 argument is C<$self> with its indexes already set from the constructor.
186 To generate accessors you list them when using the module:
188 use Test2::Util::HashBase qw/foo/;
190 This will generate the following subs in your namespace:
196 Getter, used to get the value of the C<foo> field.
200 Setter, used to set the value of the C<foo> field.
204 Constant, returns the field C<foo>'s key into the class hashref. Subclasses will
205 also get this function as a constant, not simply a method, that means it is
206 copied into the subclass namespace.
208 The main reason for using these constants is to help avoid spelling mistakes
209 and similar typos. It will not help you if you forget to prefix the '+' though.
215 You can subclass an existing HashBase class.
217 use base 'Another::HashBase::Class';
218 use Test2::Util::HashBase qw/foo bar baz/;
220 The base class is added to C<@ISA> for you, and all constants from base classes
221 are added to subclasses automatically.
225 The source code repository for Test2 can be found at
226 F<http://github.com/Test-More/test-more/>.
232 =item Chad Granum E<lt>exodist@cpan.orgE<gt>
240 =item Chad Granum E<lt>exodist@cpan.orgE<gt>
246 Copyright 2016 Chad Granum E<lt>exodist@cpan.orgE<gt>.
248 This program is free software; you can redistribute it and/or
249 modify it under the same terms as Perl itself.
251 See F<http://dev.perl.org/licenses/>