[system] / trunk / pg / lib / Parser / Value.pm Repository:
ViewVC logotype

View of /trunk/pg/lib/Parser/Value.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5509 - (download) (as text) (annotate)
Sat Sep 15 00:56:51 2007 UTC (12 years, 2 months ago) by dpvc
File size: 3616 byte(s)
Formula objects and Context objects contain reference loops, which
prevent them from being freed properly by perl when they are no longer
needed.  This is a source of an important memory leak in WeBWorK.  The
problem has been fixed by using Scalar::Util::weaken for these
recursive references, so these objects can be freed properly when they
go out of scope.  This should cause an improvement in the memory usage
of the httpd child processes.

    1 #########################################################################
    2 #
    3 #  Class that allows Value.pm objects to be included in formulas
    4 #    (used to store constant Vector values, etc.)
    5 #
    6 package Parser::Value;
    7 use strict;
    8 our @ISA = qw(Parser::Item);
    9 
   10 $Parser::class->{Value} = 'Parser::Value';
   11 
   12 #
   13 #  Get the Value.pm type of the constant
   14 #  Return it if it is an equation
   15 #  Make a new string or number if it is one of those
   16 #  Error if we don't know what it is
   17 #  Otherwise, get a Value object for the item and use it.
   18 #
   19 sub new {
   20   my $self = shift; my $class = ref($self) || $self;
   21   my $equation = shift; my $context = $equation->{context};
   22   my ($value,$ref) = @_;
   23   $value = $value->[0] if ref($value) eq 'ARRAY' && scalar(@{$value}) == 1;
   24   my $type = Value::getType($equation,$value);
   25   return $value->{tree}->copy($equation) if ($type eq 'Formula');
   26   return $self->Item("String",$context)->new($equation,$value,$ref) if ($type eq 'String');
   27   return $self->Item("String",$context)->newInfinity($equation,$value,$ref) if ($type eq 'Infinity');
   28   return $self->Item("Number",$context)->new($equation,$value,$ref) if ($type eq 'Number');
   29   return $self->Item("Number",$context)->new($equation,$value->{data},$ref)
   30     if ($type eq 'value' && $value->class eq 'Complex');
   31   $equation->Error(["Can't convert %s to a constant",Value::showClass($value)],$ref)
   32     if ($type eq 'unknown');
   33   $type = $context->Package($type), $value = $type->new($context,@{$value}) unless $type eq 'value';
   34   $type = $value->typeRef;
   35 
   36   my $c = bless {
   37     value => $value, type => $type, isConstant => 1,
   38     ref => $ref, equation => $equation,
   39   }, $class;
   40   $c->weaken;
   41   $c->check;
   42   return $c;
   43 }
   44 
   45 #
   46 #  Set flags for the object
   47 #
   48 sub check {
   49   my $self = shift;
   50   my $type = $self->{type}; my $value = $self->{value};
   51   $self->{isZero} = $value->isZero;
   52   $self->{isOne}  = $value->isOne;
   53 }
   54 
   55 #
   56 #  Return the Value object
   57 #
   58 sub eval {(shift)->{value}}
   59 
   60 #
   61 #  Call the Value object's reduce method and reset the flags
   62 #
   63 sub reduce {
   64   my $self = shift;
   65   $self->{value} = $self->{value}->reduce;
   66   $self->check;
   67   return $self;
   68 }
   69 
   70 #
   71 #  Pass on the request to the Value object
   72 #
   73 sub canBeInUnion {(shift)->{value}->canBeInUnion}
   74 
   75 #
   76 #  Return the item's list of coordinates
   77 #    (for points, vectors, matrices, etc.)
   78 #
   79 sub coords {
   80   my $self = shift;
   81   return [$self->{value}] unless $self->typeRef->{list};
   82   my @coords = (); my $equation = $self->{equation};
   83   my $value = $self->Item("Value");
   84   foreach my $x (@{$self->{value}->data}) {push(@coords,$value->new($equation,[$x]))}
   85   return [@coords];
   86 }
   87 
   88 #
   89 #  Call the appropriate formatter from Value.pm
   90 #
   91 sub string {
   92   my $self = shift; my $precedence = shift;
   93   my $string = $self->{value}->string($self->{equation},$self->{open},$self->{close},$precedence);
   94   return $string;
   95 }
   96 sub TeX {
   97   my $self = shift; my $precedence = shift;
   98   my $TeX = $self->{value}->TeX($self->{equation},$self->{open},$self->{close},$precedence);
   99   return $TeX;
  100 }
  101 sub perl {
  102   my $self = shift; my $parens = shift; my $matrix = shift;
  103   my $perl = $self->{value}->perl(0,$matrix);
  104   $perl = '('.$perl.')' if $parens;
  105   return $perl;
  106 }
  107 
  108 sub ijk {(shift)->{value}->ijk}
  109 
  110 #
  111 #  Convert the value to a Matrix object
  112 #
  113 sub makeMatrix {
  114   my $self = shift; my $context = $self->context;
  115   my ($name,$open,$close) = @_;
  116   $self->{type}{name} = $name;
  117   $self->{value} = $self->Package("Matrix",$context)->new($context,$self->{value}->value);
  118 }
  119 
  120 #
  121 #  Get a Union object's data
  122 #
  123 sub makeUnion {@{shift->{value}{data}}}
  124 
  125 #########################################################################
  126 
  127 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9