Ancient

 view release on metacpan or  search on metacpan

lib/object.pm  view on Meta::CPAN

        close $self->fh if $self->fh;
    }
    
    package main;
    object::define('FileHandle', 'fh', 'path:Str');

Zero overhead: The DESTROY wrapper is only installed for classes that
define a DEMOLISH method.

=head1 ROLES

Roles provide reusable bundles of slots and methods that can be composed
into classes. Zero overhead if not used.

=head2 object::role($name, @slot_specs)

Define a role with slots:

    object::role('Serializable', 'format:Str:default(json)');
    
    package Serializable;
    sub serialize {
        my $self = shift;
        return $self->format eq 'json' ? to_json($self) : to_yaml($self);
    }

=head2 object::requires($role, @method_names)

Declare methods that consuming classes must implement:

    object::requires('Serializable', 'to_hash');

=head2 object::with($class, @roles)

Compose roles into a class:

    object::define('Document', 'title:Str', 'content:Str');
    object::with('Document', 'Serializable');
    
    my $doc = new Document title => 'Test', content => 'Hello';
    print $doc->format;      # 'json' (from role)
    print $doc->serialize;   # JSON output

=head2 object::does($obj_or_class, $role)

Check if an object or class consumes a role:

    if (object::does($doc, 'Serializable')) { ... }

=head1 METHOD MODIFIERS

Wrap existing methods with before, after, or around hooks. Zero overhead
for classes that don't use modifiers.

=head2 object::before($method, $callback)

Run code before a method. Arguments are passed to the callback.

    object::before('Person::save', sub {
        my ($self) = @_;
        $self->updated_at(time);
    });

=head2 object::after($method, $callback)

Run code after a method. Arguments are passed to the callback.

    object::after('Person::save', sub {
        my ($self) = @_;
        log_action("Saved person: " . $self->name);
    });

=head2 object::around($method, $callback)

Wrap a method. Receives C<$orig> as first argument:

    object::around('Person::age', sub {
        my ($orig, $self, @args) = @_;
        if (@args) {
            die "Age must be positive" if $args[0] < 0;
        }
        return $self->$orig(@args);
    });

Multiple modifiers can be stacked:

    object::before('Class::method', \&first);
    object::before('Class::method', \&second);  # runs before first
    object::after('Class::method', \&third);    # runs after method
    object::after('Class::method', \&fourth);   # runs after third

=head1 PERFORMANCE COMPARISON

Method-style accessors (C<$obj-E<gt>name>):

    GET: 23-28M/s
    SET: 23-29M/s

Function-style accessors (C<name $obj>):

    GET: 63-68M/s  (22% faster than slot, 2.7x faster than method-style)
    SET: 100-175M/s (4x faster than method-style)

For comparison:

    hash->{key}:  45-74M/s
    slot:         52-59M/s GET, 149-360M/s SET

=head1 AUTHOR

LNATION E<email@lnation.org>

=head1 LICENSE

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

=cut



( run in 1.044 second using v1.01-cache-2.11-cpan-e1769b4cff6 )