Util::H2O::More - like if bless created accessors for you. Intended for hash reference-based Perl OOP only. This module uses Util::H2O::h2o as the basis for actual object creation; but there's no reason other accessor makers couldn't have been used or can be used. I just really like h2o. :-)

NOTE: baptise_deeply has been removed favour of properly handling the -recurse subroutine flag. Also, this is longer experimental.


Creating a new module using baptise instead of bless, which means it includes accessors (thanks to Util::H2O::h2o). Below is an example of a traditional Perl OOP class constructor using baptise to define a set of default accessors, in addition to any that are created by virtue of the %opts passed.

    use strict;
    use warnings;
    package Foo::Bar;

    # exports 'h2o' also
    use Util::H2O::More qw/baptise/;
    sub new {
      my $pkg    = shift;
      my %opts   = @_;
      # replaces bless, defines default constructures and creates
      # constructors based on what's passed into %opts
      my $self = baptise \%opts, $pkg, qw/bar haz herp derpes/;
      return $self;

Then on a client script,

    use strict;
    use warnings;
    use Foo::Bar;
    my $foo = Foo::Bar->new(some => q{thing}, else => 4);
    print $foo->some . qq{\n};
    # set bar via default accessor
    print $foo->bar . qq{\n};
    # default accessors also available from the class defined
    # above,
    #   $foo->haz, $foo->herp, $foo->derpes
    # and from the supplied tuple,
    #   $foo->else

For more example, please look at the classes created for the unit tests contained in t/lib. More examples may be forthcoming as this module matures.


The primary method, baptise, essentially provides the same interface as the core keyword bless with an additional slurpy third parameter where one may specify a list of default accessors.

Why Was This Created?

The really short answer: because h2o doesn't play nice inside of the traditional Perl OOP constructor (new) idiom. This is not h2o's fault. This is my fault for wanting to use it to do something it was never meant to do.

Implied above is that I wanted to maintain the usage pattern of bless, but extend it to include the generation of accessors. I wanted a better bless.

The long answer...

h2o is a deceptively powerful tool that, above all, makes it easy and fun to add accessors to ad hoc hash references that many Perl developers like to use and that get emitted, unblessed by many popular modules. For example, HTTP::Tiny, Web::Scraper, and the more common select% methods DBI flavors implement.

The usage pattern of h2o begs it to be able to support being used as a drop in replacement for bless. However, this is not h2o's original intent and it will not work as a better bless. But is does a fine job as serving as the basis for a better bless.


baptise $hash_ref, $pkg, LIST

Takes the same first 2 parameters as bless; with the addition of a list that defines a set of default accessors that do not rely on the top level keys of the provided hash reference.

baptise -recurse, $hash_ref, $pkg, LIST

Like baptise, but creates accessors recursively for a nested hash reference. Uses h2o's -recurse flag.

Note: The accessors created in the nested hashes are handled directly by h2o by utilizing the -recurse flag. This means that they will necessarily be blessed using the unchangable behavior of h2o, which maintains the name space of Util::H2O::_$hash even if h2o is passed with the -isa and -class flags, which are both utilized to achieve the effective outcome of baptise and bastise -recurse.

opt2h2o LIST

Handy function for working with Getopt::Long, which takes a list of options meant for Getopt::Long; and extracts the flag names so that they may be used to create default accessors without having more than one list. E.g.,

    use Getopt::Long qw//;
    my @opts = (qw/option1=s options2=s@ option3 option4=i o5|option5=s/);
    my $o = h2o {}, opt2h2o(@opts);
    Getopt::Long::GetOptionsFromArray( \@ARGV, $o, @opts ); # Note, @ARGV is passed by reference
    # now options are all available as accessors, e.g.:
    if ($o->option3) {

Note: default values for options may still be placed inside of the anonymous hash being objectified via h2o. This will work perfectly well with baptise and friends.

    use Getopt::Long qw//;
    my @opts = (qw/option1=s options2=s@ option3 option4=i o5|option5=s/);
    my $o = h2o { option1 => q{foo} }, opt2h2o(@opts);
    Getopt::Long::GetOptionsFromArray( \@ARGV, $o, @opts ); # Note, @ARGV is passed by reference 

    # ...
    # now $o can be used to query all possible options, even if they were
    # never passed at the commandline 
o2h REF

Uses Util::H2O::o2h, so behaves identical to it. A new hash reference is returned, unlike h2o or baptise. See Util::H2O's POD for a lot more information.

This method complements h2o or baptise very well in the sitution, e.g., when one is dealing with an ad hoc object that then needs to be sent as a serialzied JSON string. It's convenient to be able to get the un<bless>'d data structure most JSON encoding methods are expecting.

Implementation note:

Access to Util::H2O::o2h, but adjusts $Util::H2O::_PACKAGE_REGEX to accept package names that are generated by Util::H2O::More::baptise.

Historical Note:

Util::H2O::More::o2h preceded Util::H2O::o2h, and the author of the latter added it after seeing it's usefulness in cases where the ability to get a pure HASH reference after having objectified was useful. A good example is the standard dislike JSON modules' encode_json method implementations have for blessed references; this also affects environments like Dancer2 or Mojo that employ automatic serialization steps beyond route handlers. Returning a blessed reference would cause the underlying serialization routines to warn or die without using o2h to return a pure HASH reference.

baptise_deeply, $hash_ref, $pkg, LIST

This has been removed.



Because Util::H2O::More exports h2o as the basis for its operations, h2o is also available without needing to qualify its full name space.


Requires Util::H2O because this module is effectively a wrapper around h2o.

It also uses the state keyword, which is only available in perls >= 5.10.


Yes, I mean maybe. Buyer beware.




Oodler 577 <>