sub subtract {
  my ($left, $r, $rev) = @_;
  my $class = ref $left;
  if (ref $r) {
    if (UNIVERSAL::isa($r, __PACKAGE__)) {
      return $class->new($left->num * $r->den - $r->num * $left->den,
			   $r->den * $left->den);
    } else {
      croak "Can't subtract a ", $class, " from a ", ref $r;
    }
  } else {
    if ($r =~ /^[-+]?\d+$/) {
      $r = $class->new($r, 1);
      return $rev ? $r - $left : $left - $r;
    } else {
      return $rev ? $r - $left->to_num : $left->to_num - $r;
    }
  }
}
Véanse 
Casiano Rodríguez León
