This file is indexed.

/usr/share/perl5/JE/Scope.pm is in libje-perl 0.060-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package JE::Scope;

our $VERSION = '0.060';

use strict;
use warnings; no warnings 'utf8';

require JE::LValue;

our $AUTOLOAD;

# ~~~ We need a C<can> method.

sub find_var {
	my ($self,$var) = @_;
	my $lvalue;

	for(reverse @$self) {
		my $p = $_;
		defined($p=$p->prototype) or next  while !$p->exists($var);
		return new JE::LValue $_, $var;
	}
	# if we get this far, then we create an lvalue without a base obj
	new JE::LValue \$self->[0], $var;
}

sub new_var {
	my ($self,$var) = (shift,shift);
	my $var_obj;
	for(reverse @$self[1..$#$self]) { # Object  0  can't  be  a  call 
	                                 # object. Omitting it should the-
	                               # oretically make  things  margin-
	                            # ally faster.
		ref $_ eq 'JE::Object::Function::Call' and
			$var_obj = $_,
			last;
	}
	defined $var_obj or $var_obj = $$self[0];

	if (defined $var_obj->prop($var)) {
		$var_obj->prop($var, shift) if @_;
	}
	else {
		$var_obj->prop($var, @_ ? shift :
			$$self[0]->undefined);

		# This is very naughty code, but it works.	
		$JE::Code::Expression::_eval or $var_obj->prop({
			name => $var,
			dontdel => 1,
		});
	}

	return new JE::LValue $var_obj, $var
		unless not defined wantarray;
}

sub AUTOLOAD { # This delegates the method to the global object
	my($method) = $AUTOLOAD =~ /([^:]+)\z/;

	 # deal with various ALLCAPS names
	if($method =~ /^[A-Z]+\z/) {
		substr($method,0,0) = 'SUPER::';
		local *@;
		return eval { shift->$method(@_) };
	}

	shift->[0]->$method(@_); # ~~~ Maybe I should use goto
	                         #     to remove AUTOLOAD from
	                         #     the call stack.
}

sub DESTROY {}

1;

=head1 NAME

JE::Scope - JavaScript scope chain (what makes closures work)

=head1 DESCRIPTION

JavaScript code runs within an execution context which has a scope chain
associated with it. This class implements this scope chain. When a variable 
is accessed the objects in the scope chain are searched till the variable
is found.

A JE::Scope object can also be used as global (JE) object. Any methods it
does not understand will be delegated to the object at the bottom of the
stack (the far end of the chain), so that C<< $scope->null >> means the
same thing as C<< $scope->[0]->null >>.

Objects of this class consist of a reference to an array, the elements of
which are the objects in the chain (the first element
being the global object). (Think
of it as a stack.)

=head1 METHODS

=over 4

=item find_var($name, $value)

=item find_var($name)

This method searches through
the scope chain, starting at the end of the array, until it 
finds the
variable named by the first argument. If the second argument is
present, it sets the variable. It then returns an lvalue (a
JE::LValue object) that references the variable.

=item new_var($name, $value)

=item new_var($name)

This method creates (and optionally sets the value of) a new
variable in the variable object (the same thing that JavaScript's C<var>
keyword does) and returns an lvalue.

The variable object is the first object in the scope chain 
(searching from the top of the 
stack) that is a call object, or C<< $scope->[0] >> if no call object is 
found.

=back

=head1 CONSTRUCTOR

None. Just bless an array reference. You should not need to do
this because it is done for you by the C<JE> and C<JE::Object::Function> 
classes.

=head1 SEE ALSO

=over

=item L<JE>

=item L<JE::LValue>

=item L<JE::Object::Function>

=back

=cut