Skip to content

al-tom-ru/perl-Callable

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DISCLAIMER

Sorry for my English ...

NAME

Callable - make different things callable

SYNOPSIS

my $db = DBI->connect( ... );
my $router = My::Router->new(
    # use subroutine as handler
    '/' => Callable->(
        sub { my ($db, $request) = @_; ... },

        # inject default arguments to handler
        $db
    ),

    # use subroutine by name as handler
    '/profile' => Callable->new(
        # call handler as package method
        'Controller::Profile->home',

        # inject default arguments to handler
        db => $db,
        authenticated_only => 1
    ),

    # create class instance and use it as handler
    '/admin' => Callable->new(
        [
            # class_name => method
            'Controller::Admin' => 'home',

            # inject arguments to constructor
            db => $db
        ],

        # inject default arguments to handler
        restrictions => {role => 'admin'}
    ),
);

my $handler = $router->match($ENV{REQUEST_URI});

# send additional arguments when calling handler
my $response = $handler->(Request->new(%ENV));
print $response->dump();

DESCRIPTION

Callable is a simple wrapper for make subroutines from different sources. Can be used in applications with configurable callback maps (e.g. website router config). Inspired by PHP's callable

METHODS

new($source[, @default_args])

Create instance. Arguments:

  • $source

    See "SOURCES"

  • @default_args

    Default arguments that will be sent to handler

      my $hello = Callable->new(sub { join ', ', @_; }, 'Hello');
      print $hello->('World'); # Hello, World
      print $hello->('Bro'); # Hello, Bro
      print "$hello, World"; # Hello, World
    

overload '&{}'

Callable instance can be called like a subroutine reference:

my $foo = Callable->new( ... );
my $result = $foo->();

overload '""'

Callable instance can be interpolated:

my $foo = Callable->new( ... );
my $result = "Foo: $foo."; # same as 'Foo: ' . $foo->() . '.'

SOURCES

subroutine reference

my $foo = Callable->new(sub { ... });

subroutine name

my $foo = Callable->new('foo::bar');

Finds subroutine reference by it's name (\&{$name}). Name can be: Fully-qualified (Module::Name::sub_name) names used as is, not qualified names (sub_name) will be prefixed with package, where callable was called from (see caller):

{
    package Foo;
    sub foo { 'Foo' }
    sub bar { Callable->new('Foo::foo') }
    sub baz { Callable->new('foo') }
}

package main;

# ok, fully-qualified name 'Foo::foo', subroutine found
print Foo::bar->();

# not ok, 'foo' has no package name, so it will be interpreted as 'main::foo'
print Foo::baz->();

package method

Same as "subroutine name", but with -> before subroutine name:

# Fully-qualified
my $foo = Callable->new('Module::Name->sub_name');

# Not qualified
my $foo = Callable->new('->sub_name');

object method

my $obj = My::Class->new( ... );
my $foo = Callable->new([$obj => 'method_name']);

class and method

my $foo = Callable->new(['My::Class' => 'method_name']);

$foo->() creates My::Class instance and calls ->metod_name.

Constructor name can be specified:

my $foo = Callable->new(['My::Class->constructor_name' => 'method_name']);

$Callable::DEFAULT_CLASS_CONSTRUCTOR is used when no constructor name given (new by default)

callable

Callable instance can be cloned from another callable instance:

my $source = Callable->new(sub { ... });
my $foo = Callable->new($source);

Usable for re-create class instance ("class and method") and/or for resetting default "Arguments"

ARGUMENTS

Send arguments when calling:

my $foo = Callable->new(sub { join ',', @_ });
print $foo->(qw(Hello , World)); # prints Hello,World

Send default arguments when create instance:

my $foo = Callable->new(sub { join ',', @_ }, 'Hello');
print $foo->(qw(, World)); # prints Hello,World
print $foo->(qw(, Bro)); # prints Hello,Bro

Send arguments to class constructor:

{
    package My::Class;
    sub new {
        my $class = shift;
        return bless \@_, $class;
    }

    sub foo {
        my $self = shift;
        return join ' ', @{$self}, @_;
    }
}

my $foo = Callable->new(['My::Class', 'foo', 'Hello'], ',');
print $foo->('World'); # prints Hello , World
print $foo->('Bro'); # prints Hello , Bro

LICENSE

Copyright (C) Al Tom.

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

AUTHOR

Al Tom al-tom.ru@yandex.ru

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages