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   28165 use 5.016000;
  1         3  
  1         28  
2 1     1   5 use strict;
  1         1  
  1         31  
3 1     1   4 use warnings;
  1         5  
  1         54  
4              
5             package PerlX::Window;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.002';
9              
10 1     1   775 use Data::Alias;
  1         1277  
  1         98  
11 1     1   766 use Exporter::Shiny (our @EXPORT = qw( window window_pos ));
  1         4259  
  1         8  
12 1     1   70 use Scalar::Util qw( weaken );
  1         1  
  1         167  
13              
14             BEGIN {
15 1     1   2 my $impl;
16 1   33     6 $impl ||= eval { require Hash::FieldHash; 'Hash::FieldHash' };
  1         1328  
  1         2188  
17 1   33     3 $impl ||= do { require Hash::Util::FieldHash; 'Hash::Util::FieldHash' };
  0         0  
  0         0  
18 1         135 $impl->import('fieldhash');
19             };
20              
21             our ($window, @window);
22              
23             sub _exporter_validate_opts
24             {
25 1     1   76 my $me = shift;
26 1         2 my ($opts) = @_;
27            
28 1 50       4 return if ref $opts->{into};
29            
30 1     1   7 no strict qw(refs);
  1         2  
  1         1303  
31 1         1 *{$opts->{into} . "::window"} = \(my $tmp);
  1         5  
32 1         9 *{$opts->{into} . "::window"} = [];
  1         3  
33 1         1 $me->_setup_magic_string(\${$opts->{into} . "::window"});
  1         4  
34 1         4 $me->_setup_magic_array(\@{$opts->{into} . "::window"});
  1         9  
35             }
36              
37             my $scalar_wiz;
38             sub _setup_magic_string
39             {
40 1     1   2 shift;
41 1         1 my ($ref) = @_;
42            
43 1 50       2 if (eval { require Variable::Magic })
  1         928  
44             {
45             $scalar_wiz = Variable::Magic::wizard(
46 12     12   40 get => sub { ${$_[0]} = $window; 1 },
  12         23  
  12         32  
47 1     1   5 set => sub { $window = ${$_[0]}; 1 },
  1         3  
  1         2  
48 1         1520 );
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   2 shift;
71 1         2 my ($ref) = @_;
72            
73 1 50       4 unless (exists(&PerlX::Window::_TieArray::TIEARRAY))
74             {
75 1 50   1   6 eval q ~
  1     0   2  
  1     0   384  
  1     0   353  
  0     0   0  
  0     36   0  
  0     12   0  
  0     0   0  
  36     0   101  
  12     0   160  
  0     0   0  
  0     2   0  
  0     0   0  
  0     1   0  
  2     0   46  
  0         0  
  1         2  
  1         7  
  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         33 tie(@$ref, 'PerlX::Window::_TieArray');
97             }
98              
99             fieldhash(my %pos);
100             my $last;
101              
102             sub window (\[$@]$) :lvalue
103             {
104 20     20 1 4887 my ($ref, $n) = @_;
105            
106 20 100       100 $pos{$ref} = -1
107             unless defined $pos{$ref};
108            
109 20         39 weaken( $last = $ref );
110 20         22 ++$pos{$ref};
111            
112 20 100       59 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 14 my ($ref) = @_ ? @_ : ($last);
120 4         11 $pos{$ref};
121             }
122              
123             sub _window_on_array :lvalue
124             {
125 10     10   10 my ($ref, $n) = @_;
126 10         14 my $pos = $pos{$ref};
127            
128 10 100       20 if ($pos + $n > scalar(@$ref))
129             {
130 2         4 alias( @window = () );
131 2         4 $pos{$ref} = undef;
132 2         4 return;
133             }
134            
135 8         14 alias( @window = @{$ref}[$pos .. $pos+$n-1] );
  8         25  
136 8         17 @window;
137             }
138              
139             sub _window_on_string :lvalue
140             {
141 10     10   10 my ($ref, $n) = @_;
142 10         15 my $pos = $pos{$ref};
143            
144 10 100       22 if ($pos + $n > length($$ref))
145             {
146 2         4 my $tmp = undef;
147 2         3 alias( $window = $tmp );
148 2         10 $pos{$ref} = undef;
149 2         4 return;
150             }
151            
152 8         44 alias( $window = substr($$ref, $pos, $n) );
153 8         22 $window;
154             }
155              
156             1;
157              
158             __END__