Coro-Localize

 view release on metacpan or  search on metacpan

META.yml  view on Meta::CPAN

---
abstract: 'Localize variables to a coroutine'
author:
  - 'Rebecca Turner <becca@referencethis.com>'
build_requires: {}
configure_requires:
  ExtUtils::MakeMaker: 6.30
dynamic_config: 0
generated_by: 'Dist::Zilla version 4.300020, CPAN::Meta::Converter version 2.120921'
license: perl
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html

Makefile.PL  view on Meta::CPAN

use strict;
use warnings;



use ExtUtils::MakeMaker 6.30;



my %WriteMakefileArgs = (
  "ABSTRACT" => "Localize variables to a coroutine",
  "AUTHOR" => "Rebecca Turner <becca\@referencethis.com>",
  "BUILD_REQUIRES" => {},
  "CONFIGURE_REQUIRES" => {
    "ExtUtils::MakeMaker" => "6.30"
  },
  "DISTNAME" => "Coro-Localize",
  "EXE_FILES" => [],
  "LICENSE" => "perl",
  "NAME" => "Coro::Localize",
  "PREREQ_PM" => {

README  view on Meta::CPAN



This archive contains the distribution Coro-Localize,
version 0.1.2:

  Localize variables to a coroutine

This software is copyright (c) 2012 by Rebecca Turner.

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


lib/Coro/Localize.pm  view on Meta::CPAN

# ABSTRACT: Localize variables to a coroutine
package Coro::Localize;
{
  $Coro::Localize::VERSION = '0.1.2';
}
use common::sense;
use Devel::Declare;
use Data::Alias ();

sub import {
    my $class = shift;
    $class->import_into( scalar caller );
}

my $stub = sub {};
sub import_into {
    my $class = shift;
    my( $target ) = @_;
    Devel::Declare->setup_for( $target => { corolocal => {const => \&parser} } );
    *{$target.'::corolocal'} = $stub;
}

our $prefix = '';
sub get {substr Devel::Declare::get_linestr, length $prefix}
sub set {       Devel::Declare::set_linestr $prefix . $_[0]}

# croak that ignores Devel::Declare and our own package when determining the
# line to blame.
# Rewritten from a version in Begin::Declare
sub croak {

lib/Coro/Localize.pm  view on Meta::CPAN

    set ";" . $code . get;
}

sub strip_space {
    my $skip = Devel::Declare::toke_skipspace length $prefix;
    set substr get, $skip;
}

sub strip_keyword {
    strip_space;
    get =~ /^(corolocal)(?:\b|$)/ or croak "Could not match corolocal", get;
    $prefix .= $1;
    return $1;
}

sub strip_comma {
    if ( get =~ /^,/) {
        $prefix .= ' ';
        return 1;
    }
    else {

lib/Coro/Localize.pm  view on Meta::CPAN

1;


__END__
=pod

=encoding utf-8

=head1 NAME

Coro::Localize - Localize variables to a coroutine

=head1 VERSION

version 0.1.2

=head1 SYNOPSIS

    use feature qw( say );
    use Coro;
    use Coro::EV;
    use Coro::Localize;
    # Or with Syntax::Feature:
    # use syntax qw( corolocal );
     
    our $scalar = "main loop";
     
    async {
        corolocal $scalar = "thread 1";
        say "# 1 - $scalar";
        cede;
        say "# 3 - $scalar";
        cede;
        say "# 5 - $scalar";
    };
     
    async {
        corolocal $scalar = "thread 2";
        say "# 2 - $scalar";
        cede;
        say "# 4 - $scalar";
        cede;
        say "# 6 - $scalar";
    };

    say "# starting $scalar";
    EV::loop;
    say "# complete $scalar";

lib/Coro/Localize.pm  view on Meta::CPAN

    # 1 - thread 1
    # 2 - thread 2
    # 3 - thread 1
    # 4 - thread 2
    # 5 - thread 1
    # 6 - thread 2
    # complete main loop

=head1 DESCRIPTION

This provides a new keyword, "corolocal" that works will localize a variable
to a particular coroutine.  This allows you to have thread-local values for
global variables.  It can localize scalars, arrays and hashes.

=head1 IMPLEMENTATION

It localizes variables by Coro on_enter and on_leave blocks combined with
Data::Alias to fiddle with where the variable points.

    corolocal $/ = \2_048;

Is exactly equivalent to:

    use Data::Alias;
    my(%external_values,%internal_values);
    @internal_values{qw($/)} = ();
    alias $external_values{'$/'} = $/;
    Coro::on_enter {
        alias $/ = $internal_values{'$/'};
    };

lib/Syntax/Feature/Corolocal.pm  view on Meta::CPAN

=head1 NAME

Syntax::Feature::Corolocal - Corolocal for Syntax::Feature

=head1 VERSION

version 0.1.2

=head1 SYNOPSIS

    use syntax qw( corolocal );
    
    async {    
        corolocal $/ = \2_048;
        while (<STDIN>) {
            # ...
        }
    }

=head1 DESCRIPTION

This allows you to load L<Coro::Localize> using L<Syntax::Feature>. 
L<Syntax::Feature> provides a single point of entry for loading various
syntax extensions.

t/array.t  view on Meta::CPAN

use Test::More tests => 8;
use Coro;
use Coro::Localize;
 
our @array = qw( main loop );

my @threads; 
push @threads, async {
    corolocal @array = qw( thread 1 );
    is( "1 - @array", "1 - thread 1", "array thread 1, test 1" );
    cede;
    is( "3 - @array", "3 - thread 1", "array thread 1, test 2" );
    cede;
    is( "5 - @array", "5 - thread 1", "array thread 1, test 3" );
};
 
push @threads, async {
    corolocal @array = qw( thread 2 );
    is( "2 - @array", "2 - thread 2", "array thread 2, test 1" );
    cede;
    is( "4 - @array", "4 - thread 2", "array thread 2, test 2" );
    cede;
    is( "6 - @array", "6 - thread 2", "array thread 2, test 3" );
};

is( "@array", "main loop", "array main, test 1" );
$_->join for @threads;
is( "@array", "main loop", "array main, test 2" );

t/hash.t  view on Meta::CPAN

use Test::More tests => 8;
use Coro;
use Coro::Localize;
 
our %hash = qw( main loop );

my @threads; 
push @threads, async {
    corolocal %hash = qw( thread 1 );
    is( "1 - @{[ map {qq{$_ => $hash{$_}}} keys %hash ]}", "1 - thread => 1", "hash thread 1, test 1" );
    cede;
    is( "3 - @{[ map {qq{$_ => $hash{$_}}} keys %hash ]}", "3 - thread => 1", "hash thread 1, test 2" );
    cede;
    is( "5 - @{[ map {qq{$_ => $hash{$_}}} keys %hash ]}", "5 - thread => 1", "hash thread 1, test 3" );
};
 
push @threads, async {
    corolocal %hash = qw( thread 2 );
    is( "2 - @{[ map {qq{$_ => $hash{$_}}} keys %hash ]}", "2 - thread => 2", "hash thread 2, test 1" );
    cede;
    is( "4 - @{[ map {qq{$_ => $hash{$_}}} keys %hash ]}", "4 - thread => 2", "hash thread 2, test 2" );
    cede;
    is( "6 - @{[ map {qq{$_ => $hash{$_}}} keys %hash ]}", "6 - thread => 2", "hash thread 2, test 3" );
};

is( "@{[ map {qq{$_ => $hash{$_}}} keys %hash ]}", "main => loop", "hash main, test 1" );
$_->join for @threads;
is( "@{[ map {qq{$_ => $hash{$_}}} keys %hash ]}", "main => loop", "hash main, test 2" );

t/scalar.t  view on Meta::CPAN

use Test::More tests => 8;
use Coro;
use Coro::Localize;
 
our $scalar = "main loop";

my @threads; 
push @threads, async {
    corolocal $scalar = "thread 1";
    is( "1 - $scalar", "1 - thread 1", "scalar thread 1, test 1" );
    cede;
    is( "3 - $scalar", "3 - thread 1", "scalar thread 1, test 2" );
    cede;
    is( "5 - $scalar", "5 - thread 1", "scalar thread 1, test 3" );
};
 
push @threads, async {
    corolocal $scalar = "thread 2";
    is( "2 - $scalar", "2 - thread 2", "scalar thread 2, test 1" );
    cede;
    is( "4 - $scalar", "4 - thread 2", "scalar thread 2, test 2" );
    cede;
    is( "6 - $scalar", "6 - thread 2", "scalar thread 2, test 3" );
};

is( $scalar, "main loop", "scalar main, test 1" );
$_->join for @threads;
is( $scalar, "main loop", "scalar main, test 2" );

t/syntax-feature.t  view on Meta::CPAN

        require syntax;
    };
    if ( $@ ) {
        Test::More->import( skip_all => "Syntax::Feature not installed\n$@" );
    }
    else {
        Test::More->import( tests => 8 );
    }
}
use Coro;
use syntax qw( corolocal );
 
our $scalar = "main loop";

my @threads; 
push @threads, async {
    corolocal $scalar = "thread 1";
    is( "1 - $scalar", "1 - thread 1", "scalar thread 1, test 1" );
    cede;
    is( "3 - $scalar", "3 - thread 1", "scalar thread 1, test 2" );
    cede;
    is( "5 - $scalar", "5 - thread 1", "scalar thread 1, test 3" );
};
 
push @threads, async {
    corolocal $scalar = "thread 2";
    is( "2 - $scalar", "2 - thread 2", "scalar thread 2, test 1" );
    cede;
    is( "4 - $scalar", "4 - thread 2", "scalar thread 2, test 2" );
    cede;
    is( "6 - $scalar", "6 - thread 2", "scalar thread 2, test 3" );
};

is( $scalar, "main loop", "scalar main, test 1" );
$_->join for @threads;
is( $scalar, "main loop", "scalar main, test 2" );



( run in 0.499 second using v1.01-cache-2.11-cpan-3cd7ad12f66 )