NAME

Object::Instant - Create objects without those pesky classes

SYNOPSIS

use Object::Instant;

my $obj = Object::Instant->new(sub {
              my ($self, $method, @args) = @_;

              print "self: $self, method name: $method, first arg: $args[0]\n";
          });

$obj->whatever(123);
## self: Object::Instant=HASH(0xc78eb0), method name: whatever, first arg: 123

DESCRIPTION

Sometimes you want something that acts like an object but you don't want to go to all the trouble of creating a new package, with constructor and methods and so on. This module is a trivial wrapper around perl's AUTOLOAD functionality which intercepts method calls and lets you handle them in a single sub.

USE-CASES

AUTOLOAD SYNTACTIC SUGAR

AUTOLOAD allows you to dispatch on method names at run-time which can sometimes be useful, for example in RPC protocols where you transmit method call messages to another process for them to be executed remotely. Unfortunately, using AUTOLOAD is a bit annoying since the interface is somewhat arcane. Object::Instance is a nicer interface to the most commonly used AUTOLOAD functionality:

my $obj = Object::Instant->new(sub {
            my ($self, $method, @args) = @_;

            my $rpc_input = encode_json({ method => $method, args => [ @args ] });

            my $rpc_output = do_rpc_call($rpc_input);

            return decode_json($rpc_output);
          });

PLACE-HOLDER OBJECTS

Some APIs require you to pass in or provide an object but then don't actually end up using it. Instead of passing in undef and getting a weird Can't call method "XYZ" on an undefined value error, you can pass in an Object::Instant which will throw a helpful exception instead:

my $obj = Some::Api->new(
            error_logger => Object::Instant->new(sub {
                              die "Please provide an 'error_logger' object to Some::API"
                            })
          );

LAZY OBJECT CREATION

Again, some APIs may never end up using an object so you may wish to "lazily" defer the creation of that object until a method is actually called on it.

For example, suppose you have a large CGI script which always opens a DBI connection but only actually accesses this connection for a small portion of runs. You can prevent the script from accessing the database on the majority of runs with Object::Instant:

my $dbh = Object::Instant->new(sub {
            require DBI;
            $_[0] = DBI->connect($dsn, $user, $pass, { RaiseError => 1)
                || die "Unable to connect to database: $DBI::errstr";

            my ($self, $method, @args) = @_;

            return $self->$method(@args);
          });

This works because the $_[0] argument is actually an alias to $dbh. After you call a method on $dbh for the first time it will change from a Object::Instant object into a DBI object (assuming the DBI->connect constructor succeeds).

To demonstrate this, here is an example with Session::Token:

my $o = Object::Instant->new(sub {
          require Session::Token;
          $_[0] = Session::Token->new;

          my ($self, $method, @args) = @_;
          return $self->$method(@args);
        });

say ref $o;
## Object::Instant

say $o->get;
## mhDPtfLlFMGl5kyNcJgFt7

say ref $o;
## Session::Token

SEE ALSO

Object-Instant github repo

AUTHOR

Doug Hoyte, <doug@hcsw.org>

COPYRIGHT & LICENSE

Copyright 2015 Doug Hoyte.

This module is licensed under the same terms as perl itself.