NAME Object::Sub - Create objects without those pesky classes SYNOPSIS use Object::Sub; my $obj = Object::Sub->new(sub { my ($self, $method, @args) = @_; print "self: $self, method name: $method, first arg: $args[0]\n"; }); $obj->whatever(123); ## self: Object::Sub=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::Sub->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::Sub which will throw a helpful exception instead: my $obj = Some::API->new( error_logger => Object::Sub->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::Sub: my $dbh = Object::Sub->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::Sub" object into a "DBI" object (assuming the "DBI->connect" constructor succeeds). To demonstrate this, here is an example with Session::Token: my $o = Object::Sub->new(sub { require Session::Token; $_[0] = Session::Token->new; my ($self, $method, @args) = @_; return $self->$method(@args); }); say ref $o; ## Object::Sub say $o->get; ## mhDPtfLlFMGl5kyNcJgFt7 say ref $o; ## Session::Token SEE ALSO Object-Sub github repo AUTHOR Doug Hoyte, "" COPYRIGHT & LICENSE Copyright 2015 Doug Hoyte. This module is licensed under the same terms as perl itself.