File Coverage

blib/lib/PerlX/Window.pm
Criterion Covered Total %
statement 88 103 85.4
branch 13 22 59.0
condition 2 6 33.3
subroutine 22 32 68.7
pod 2 2 100.0
total 127 165 76.9


line stmt bran cond sub pod time code
1 1     1   27233 use 5.016000;
  1         3  
  1         33  
2 1     1   6 use strict;
  1         1  
  1         36  
3 1     1   5 use warnings;
  1         6  
  1         140  
4              
5             package PerlX::Window;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.004';
9              
10 1     1   1037 use Data::Alias;
  1         3067  
  1         112  
11 1     1   916 use Exporter::Shiny (our @EXPORT = qw( window window_pos ));
  1         12932  
  1         12  
12 1     1   86 use Scalar::Util qw( weaken );
  1         4  
  1         217  
13              
14             BEGIN {
15 1     1   2 my $impl;
16 1   33     6 $impl ||= eval { require Hash::FieldHash; 'Hash::FieldHash' };
  1         1079  
  1         1938  
17 1   33     5 $impl ||= do { require Hash::Util::FieldHash; 'Hash::Util::FieldHash' };
  0         0  
  0         0  
18 1         118 $impl->import('fieldhash');
19             };
20              
21             our ($window, @window);
22              
23             sub _exporter_validate_opts
24             {
25 1     1   67 my $me = shift;
26 1         2 my ($opts) = @_;
27            
28 1 50       4 return if ref $opts->{into};
29            
30 1     1   6 no strict qw(refs);
  1         2  
  1         818  
31 1         2 *{$opts->{into} . "::window"} = \(my $tmp);
  1         6  
32 1         11 *{$opts->{into} . "::window"} = [];
  1         4  
33 1         2 $me->_setup_magic_string(\${$opts->{into} . "::window"});
  1         4  
34 1         3 $me->_setup_magic_array(\@{$opts->{into} . "::window"});
  1         11  
35             }
36              
37             my $scalar_wiz;
38             sub _setup_magic_string
39             {
40 1     1   2 shift;
41 1         2 my ($ref) = @_;
42            
43 1 50       2 if (eval { require Variable::Magic })
  1         2349  
44             {
45             $scalar_wiz = Variable::Magic::wizard(
46 12     12   49 get => sub { ${$_[0]} = $window; 1 },
  12         28  
  12         42  
47 1     1   6 set => sub { $window = ${$_[0]}; 1 },
  1         5  
  1         5  
48 1         1449 );
49 1         47 Variable::Magic::cast($ref, $scalar_wiz);
50             }
51             else
52             {
53 0 0       0 unless (exists(&PerlX::Window::_TieScalar::TIESCALAR))
54             {
55 0 0       0 eval q ~
56             package #
57             PerlX::Window::_TieScalar;
58             sub TIESCALAR { my $tmp = undef; bless \$tmp, $_[0] }
59             sub FETCH { $PerlX::Window::window }
60             sub STORE { $PerlX::Window::window = $_[1] }
61             1;
62             ~ or die("Something went horribly wrong: $@");
63             }
64 0         0 tie($$ref, 'PerlX::Window::_TieScalar');
65             }
66             }
67              
68             sub _setup_magic_array
69             {
70 1     1   3 shift;
71 1         2 my ($ref) = @_;
72            
73 1 50       5 unless (exists(&PerlX::Window::_TieArray::TIEARRAY))
74             {
75 1 50   1   8 eval q ~
  1     0   2  
  1     0   409  
  1     0   79  
  0     0   0  
  0     36   0  
  0     12   0  
  0     0   0  
  36     0   135  
  12     0   259  
  0     0   0  
  0     2   0  
  0     0   0  
  0     1   0  
  2     0   59  
  0         0  
  1         2  
  1         8  
  0         0  
76             package #
77             PerlX::Window::_TieArray;
78             use Carp;
79             sub TIEARRAY { my $tmp = undef; bless \$tmp, $_[0] }
80             sub STORE { $PerlX::Window::window[ $_[1] ] = $_[2] }
81             sub FETCH { $PerlX::Window::window[ $_[1] ] }
82             sub FETCHSIZE { scalar @PerlX::Window::window }
83             sub STORESIZE { croak("Array has a fixed size") }
84             sub EXTEND { () }
85             sub EXISTS { !!1 }
86             sub DELETE { croak("Array element cannot be deleted") }
87             sub CLEAR { croak("Array has a fixed size") }
88             sub PUSH { croak("Array has a fixed size") }
89             sub POP { croak("Array has a fixed size") }
90             sub SHIFT { croak("Array has a fixed size") }
91             sub UNSHIFT { croak("Array has a fixed size") }
92             sub SPLICE { croak("Array has a fixed size") }
93             1;
94             ~ or die("Something went horribly wrong: $@");
95             }
96 1         35 tie(@$ref, 'PerlX::Window::_TieArray');
97             }
98              
99             fieldhash(my %pos);
100             my $last;
101              
102             sub window (\[$@]$) :lvalue
103             {
104 20     20 1 6291 my ($ref, $n) = @_;
105            
106 20 100       79 $pos{$ref} = -1
107             unless defined $pos{$ref};
108            
109 20         47 weaken( $last = $ref );
110 20         30 ++$pos{$ref};
111            
112 20 100       70 ref($ref) eq 'ARRAY'
113             ? _window_on_array(@_)
114             : _window_on_string(@_);
115             }
116              
117             sub window_pos (;\[$@]) :lvalue
118             {
119 4 50   4 1 18 my ($ref) = @_ ? @_ : ($last);
120 4         13 $pos{$ref};
121             }
122              
123             sub _window_on_array :lvalue
124             {
125 10     10   14 my ($ref, $n) = @_;
126 10         15 my $pos = $pos{$ref};
127            
128 10 100       26 if ($pos + $n > scalar(@$ref))
129             {
130 2         7 alias( @window = () );
131 2         4 $pos{$ref} = undef;
132 2         6 return;
133             }
134            
135 8         16 alias( @window = @{$ref}[$pos .. $pos+$n-1] );
  8         33  
136 8         27 @window;
137             }
138              
139             sub _window_on_string :lvalue
140             {
141 10     10   16 my ($ref, $n) = @_;
142 10         18 my $pos = $pos{$ref};
143            
144 10 100       26 if ($pos + $n > length($$ref))
145             {
146 2         3 my $tmp = undef;
147 2         5 alias( $window = $tmp );
148 2         4 $pos{$ref} = undef;
149 2         14 return;
150             }
151            
152 8         56 alias( $window = substr($$ref, $pos, $n) );
153 8         28 $window;
154             }
155              
156             1;
157              
158             __END__