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

View of /trunk/pg/lib/Parser/Number.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: 2450 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 #  Implements the Number class
    4 #
    5 package Parser::Number;
    6 use strict;
    7 our @ISA = qw(Parser::Item);
    8 
    9 $Parser::class->{Number} = 'Parser::Number';
   10 
   11 sub new {
   12   my $self = shift; my $class = ref($self) || $self;
   13   my $equation = shift; my $context = $equation->{context};
   14   my $num; my ($value,$ref) = @_;
   15   return $self->Item("Complex",$context)->new($equation,$value,$ref)
   16     if (ref($value) eq 'ARRAY');
   17   $value = $value->value while Value::isReal($value);
   18   $num = bless {
   19     value => $value + 0, # format the value as a number, just in case
   20     value_string => $value, # for decimal checking, etc.
   21     type => $Value::Type{number}, isConstant => 1,
   22     ref => $ref, equation => $equation,
   23   }, $class;
   24   $num->weaken;
   25   my $x = $num->Package("Real")->make($context,$value);
   26   $num->{isOne}  = 1 if $x eq 1;
   27   $num->{isZero} = 1 if $value == 0;
   28   return $num;
   29 }
   30 
   31 #
   32 #  We know the answers to these, so no need to compute them
   33 #
   34 sub isComplex {0}
   35 sub isNumber {1}
   36 sub isRealNumber {1}
   37 
   38 #
   39 #  Return the value
   40 #
   41 sub eval {(shift)->{value}}
   42 
   43 #
   44 #  If the number is negative, factor it out and
   45 #    try using that in the reductions of the parent objects.
   46 #
   47 sub reduce {
   48   my $self = shift; my $context = $self->context;
   49   my $reduce = $context->{reduction};
   50   if ($reduce->{'-n'} && $self->{value} < 0) {
   51     $self->{value} = -($self->{value});
   52     $self = Parser::UOP::Neg($self);
   53     $self->{op}{isOne} = 1 if $self->Package("Real")->make($context,$self->{op}{value}) eq 1;
   54   }
   55   return $self;
   56 }
   57 
   58 $Parser::reduce->{'-n'} = 1;
   59 
   60 
   61 #
   62 #  Call the Value::Real versions to format numbers
   63 #
   64 sub string {
   65   my $self = shift;
   66   $self->Package("Real")->make($self->context,$self->{value})->string($self->{equation},@_);
   67 }
   68 sub TeX {
   69   my $self = shift;
   70   $self->Package("Real")->make($self->context,$self->{value})->TeX($self->{equation},@_);
   71 }
   72 sub perl {
   73   my $self = shift; my $parens = shift;
   74   my $n = $self->{value};
   75   $n = '('.$n.')' if $parens && $n < 0;
   76   return $n;
   77 }
   78 
   79 ###########################################
   80 
   81 sub NoDecimals {
   82   my $context = shift || Value->context;
   83   $context->flags->set(NumberCheck=>\&_NoDecimals);
   84 }
   85 
   86 sub _NoDecimals {
   87   my $self = shift;
   88   $self->Error("You are not allowed to type decimal numbers in this problem")
   89     unless $self->{value_string} =~ m/^[-+]?[0-9]+$/;
   90 }
   91 
   92 
   93 #########################################################################
   94 
   95 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9