File: Var.pm

package info (click to toggle)
rex 1.14.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,012 kB
  • sloc: perl: 35,587; xml: 264; sh: 51; makefile: 13
file content (111 lines) | stat: -rw-r--r-- 2,628 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#
# (c) Jan Gehring <jan.gehring@gmail.com>
#

=head1 NAME

Rex::Shared::Var - Share variables across Rex tasks

=head1 DESCRIPTION

Share variables across Rex tasks with the help of Storable, using a C<vars.db.$PID> file in the local directory, where C<$PID> is the PID of the parent process.

=head1 SYNOPSIS

 BEGIN {                           # put share in a BEGIN block
   use Rex::Shared::Var;
   share qw($scalar @array %hash); # share the listed variables
 }

=head1 LIMITATIONS

Currently nesting data structures works only if the assignment is made on the top level of the structure, or when the nested structures are also shared variables. For example:

 BEGIN {
   use Rex::Shared::Var;
   share qw(%hash %nested);
 }
 
 # this doesn't work as expected
 $hash{key} = { nested_key => 42 };
 $hash{key}->{nested_key} = -1; # $hash{key}->{nested_key} still returns 42
 
 # workaround 1 - top level assignments
 $hash{key} = { nested_key => 42 };
 $hash{key} = { nested_key => -1 };
 
 # workaround 2 - nesting shared variables
 $nested{nested_key}      = 42;
 $hash{key}               = \%nested;
 $hash{key}->{nested_key} = -1;

=head1 METHODS

=cut

package Rex::Shared::Var;

use v5.12.5;
use warnings;

our $VERSION = '1.14.1'; # VERSION

use Symbol;

require Exporter;
use base qw(Exporter);
use vars qw(@EXPORT);

@EXPORT = qw(share);

=head2 share

Share the passed list of variables across Rex tasks. Should be used in a C<BEGIN> block.

 BEGIN {
   use Rex::Shared::Var;
   share qw($error_count);
 }

 task 'count', sub {
   $error_count += run 'wc -l /var/log/syslog';
 };

 after_task_finished 'count', sub {
   say "Total number of errors: $error_count";
 };

=cut

sub share {
  my @vars = @_;
  my ( $package, $file, $line ) = caller;

  my ( $sigil, $symbol );
  for my $var (@vars) {

    if ( ( $sigil, $symbol ) = ( $var =~ /^([\$\@\%\*\&])(.+)/ ) ) {
      my $ref_to_symbol = qualify_to_ref $symbol, $package;
      $symbol = "${package}::$symbol";

      if ( $sigil eq "\$" ) {
        eval "use Rex::Shared::Var::Scalar;";
        tie ${ *{$ref_to_symbol} }, "Rex::Shared::Var::Scalar", $symbol;
        *{$ref_to_symbol} = \${ *{$ref_to_symbol} };
      }
      elsif ( $sigil eq "\@" ) {
        eval "use Rex::Shared::Var::Array;";
        tie @{ *{$ref_to_symbol} }, "Rex::Shared::Var::Array", $symbol;
        *{$ref_to_symbol} = \@{ *{$ref_to_symbol} };
      }
      elsif ( $sigil eq "\%" ) {
        eval "use Rex::Shared::Var::Hash;";
        tie %{ *{$ref_to_symbol} }, "Rex::Shared::Var::Hash", $symbol;
        *{$ref_to_symbol} = \%{ *{$ref_to_symbol} };
      }
    }

  }
}

1;