NAME
   Object::Util - a selection of utility methods that can be called on
   blessed objects

SYNOPSIS
      use Object::Util;

      # $foo might be undef, but this should not die
      if ($foo->$_isa("Bar")) {
         ...;
      }

DESCRIPTION
   This module is inspired by Safe::Isa, Object::Tap, and my own OO
   experiences. It is a hopefully helpful set of methods for working with
   objects, exposed as lexical coderef variables.

 Rationale
   Providing methods as coderefs so that you can do:

      $object->$_foo(@args)

   ... is unusual, so probably requires some explanation.

   Firstly some of these methods are designed to be called on either a
   blessed object or some kind of unblessed reference or value. Calling a
   method on an unblessed reference like this will croak:

      $ref->foo(@args)

   Ditto calling methods on undef. Coderefs don't suffer from that problem.

   More importantly though, the aim of this module is that these methods
   should be available for you to call on *any* object. You can only call
   `$object->foo(@args)` if $object's class implements a method called `foo`,
   or inherits from a superclass that does. Coderef methods can be called on
   any object.

   This module adopts the $_foo naming convention pioneered by modules such
   as Safe::Isa. However (unlike Safe::Isa) the coderefs it provides are
   *true lexical variables* (a.k.a. `my` variables), not package variables
   (a.k.a. `our` variables).

 Methods
  Object construction and manipulation
   $_new
       Can be used like `$class->$_new(@args)` to create a new object.
       Object::Util will use Module::Runtime to *attempt* to load $class if
       it is not already loaded. $class is expected to provide a method
       called `new`.

       Can also be used as `$factory->$_new(@args)` to create a new object,
       where $factory is a coderef or an object overloading `&{}`. In this
       case, $_new will simply call `$factory->(@args)` and expect that to
       return an object.

   $_clone
       If the object provides a `clone` method, calls that. Or if the object
       appears to be Moose- or Mouse-based, clones it using the metaobject
       protocol.

       Otherwise takes the naive approach of treating the object as a hashref
       of attribute values, and creates a new object of the same class.

          # clone overrides some attributes from the original object
          my $glenda = $glen->$_clone(name => "Glenda", gender => "f");

       That final fallback obviously massively breaks your class'
       encapsulation, so it should be used sparingly.

   $_with_traits
       Calling `$class->$_with_traits(@traits)` will return a new class name
       that does some extra traits. Should roughly support Moose, Mouse, Moo,
       and Role::Tiny, though combinations of frameworks (e.g. consuming a
       Moose role in a Mouse class) will not always work.

       If $class is actually a (factory) coderef, then this will only
       *partly* work. Example:

          my $factory  = sub { Foo->new(@_) };
          my $instance = $factory->$_with_traits("Bar")->$_new(%args);

       The object $instance should now be a `Foo` object, and should do the
       `Bar` role, however if `Bar` defines any *attributes*, then $_new will
       not have initialized them correctly. This is because of the opacity of
       the $factory: $_with_traits cannot peek inside it and apply traits to
       the `Foo` class; instead it needs to build $instance and apply the
       traits to the already-built object. Therefore any behaviour that `Bar`
       defines for the constructor will have been ignored.

       It is sometimes possible to work around this issue using:

          my $factory  = sub { Foo->new(@_) };
          my $instance = $factory->$_with_traits("Bar")->$_new(%args);
          $instance = $instance->$_clone(%args);

   $_extend
       Calling `$object->$_extend(\@traits, \%methods)` will add some extra
       roles and/or methods to an existing object.

       Either @traits or %methods may be omitted. That is,
       `$object->$_extend(\@traits)` will add some traits to an existing
       object but no new methods, and `$object->$_extend(\%methods)` will add
       new methods, but no traits. `$object->$_extend()` also works fine, and
       is a no-op.

       This method always returns $object, which makes it suitable for
       chaining.

       Like Object::Extend, but with added support for roles.

   $_murder
       Called on an object, tries its best to destroy the object.

         my $object = Foo->new;
         $object->$_murder;
         defined($object);   # false

       Not only will $object be set to undef in the above example, but if
       there were any other references to the object, $_murder will do its
       best to poison them too.

       $_murder will empty out the contents of the underlying hash or array
       in hashref-based and arrayref-based objects, and for scalarref-based
       objects will set the underlying scalar to undef.

       $_murder will also rebless the reference into a dummy class where all
       method calls will croak.

       $_murder will generously ensure that the object's `DESTROY` is called
       before initiating the killing spree, allowing the class to perform any
       necessary clean-up first.

  Method call modifiers
   $_call_if_object
       `$object->$_call_if_object($method => @args)` works like
       `$object->$method(@args)`, but if $object is undefined, returns
       `undef` instead of throwing an exception.

       $method may be a method name, or a coderef (anonymous method).

       Same as Safe::Isa.

   $_try
       `$object->$_try($method => @args)` works like
       `$object->$method(@args)`, but if *any exception is thrown* returns
       `undef` instead.

       $method may be a method name, or a coderef (anonymous method).

   $_tap
       `$object->$_tap($method => @args)` works like
       `$object->$method(@args)`, but discards the method's return value
       (indeed it calls the method in void context), and instead returns the
       object itself, making it useful for chaining.

       $method may be a method name, or a coderef (anonymous method).

       Same as Object::Tap, or the `tap` method in Ruby.

   $_isa
       `$object->$_isa($class)` works like `isa` as defined in UNIVERSAL, but
       if $object is undefined, returns false instead of throwing an
       exception.

       A shortcut for `$object->$_call_if_object(isa => $class)`.

       Same as Safe::Isa.

   $_does
       `$object->$_does($role)` works like `does` as defined in
       Moose::Object, but if $object is undefined, returns false instead of
       throwing an exception.

       A shortcut for `$object->$_call_if_object(does => $role)`.

       Same as Safe::Isa.

   $_DOES
       `$object->$_DOES($role)` works like `DOES` as defined in UNIVERSAL,
       but if $object is undefined, returns false instead of throwing an
       exception.

       A shortcut for `$object->$_call_if_object(DOES => $role)`.

       Same as Safe::Isa.

   $_can
       `$object->$_can($method)` works like `can` as defined in UNIVERSAL,
       but if $object is undefined, returns `undef` instead of throwing an
       exception.

       There is one other significant deviation from the behaviour of
       UNIVERSAL's `can` method: $_can also returns true if $method is an
       unblessed coderef. (The behaviour of $method if it is a blessed object
       -- particularly in the face of overloading -- can be unintuitive, so
       is not supported by $_can.)

       Similar to Safe::Isa, but not quite the same.

  Object utility methods
   $_dump
       Calling `$object->$_dump` returns a Data::Dumper dump of the object,
       with some useful changes to the default Data::Dumper output. (Same as
       Data::Dumper::Concise.)

       If the object provides its own `dump` method, this will be called
       instead. Any additional arguments will be passed through to it.

   $_dwarn
       Calling `$object->$_dwarn(@args)` prints a similar dump of the object
       and any arguments as a warning, then returns the object, so is
       suitable for tap-like chaining.

       Unlike $_dump, will not call the object's own `dump` method.

   $_dwarn_call
       Calling `$object->$_dwarn_call($method, @args)` calls the method on
       the object, passing it the arguments, and returns the result. Along
       the way, it will dump the object, method, arguments, and return value
       as warnings. Returns the method's return value.

       Unlike $_dump, will not call the object's own `dump` method.

 Implementation Details
   B::Hooks::Parser is used to inject these methods into your lexical scope,
   and `Internals::SvREADONLY` (an internal function built into the Perl
   core) is used to make them read-only, so you can't do:

      use Object::Util;
      $_isa = sub { "something else" };

   If this module detects that B::Hooks::Parser cannot be used on your
   version of Perl, or your Perl is too old to have Internals::SvREADONLY,
   then it has various fallback routes, but the variables it provides may end
   up as package (`our`) variables, or not be read-only.

   If the magic works on your version of Perl, but you wish to avoid the
   magic anyway, you can switch it off:

      use Object::Util magic => 0;

   The magic may trigger bugs if you're loading Object::Util in a
   sufficiently unusual way (for example, `require` and `import` instead of
   `use`). If this happens, disable magic.

BUGS
   Please report any bugs to
   <http://rt.cpan.org/Dist/Display.html?Queue=Object-Util>.

SEE ALSO
   Safe::Isa, UNIVERSAL, Object::Tap, MooseX::Clone, Data::Dumper::Concise,
   Object::Extend.

AUTHOR
   Toby Inkster <[email protected]>.

COPYRIGHT AND LICENCE
   This software is copyright (c) 2014, 2018 by Toby Inkster.

   This is free software; you can redistribute it and/or modify it under the
   same terms as the Perl 5 programming language system itself.

DISCLAIMER OF WARRANTIES
   THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
   WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
   MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.