diff --git a/lib/linguist/heuristics.rb b/lib/linguist/heuristics.rb
index 2ff8d9fb..eb39a925 100644
--- a/lib/linguist/heuristics.rb
+++ b/lib/linguist/heuristics.rb
@@ -33,7 +33,7 @@ module Linguist
     #     disambiguate "Perl", "Prolog" do |data|
     #       if data.include?("use strict")
     #         Language["Perl"]
-    #       elsif data.include?(":-")
+    #       elsif /^[^#]+:-/.match(data)
     #         Language["Prolog"]
     #       end
     #     end
@@ -94,13 +94,13 @@ module Linguist
         Language["Perl6"]
       elsif data.match(/use strict|use\s+v?5\./)
         Language["Perl"]
-      elsif data.include?(":-")
+      elsif /^[^#]+:-/.match(data)
         Language["Prolog"]
       end
     end
 
     disambiguate "ECL", "Prolog" do |data|
-      if data.include?(":-")
+      if /^[^#]+:-/.match(data)
         Language["Prolog"]
       elsif data.include?(":=")
         Language["ECL"]
@@ -108,7 +108,7 @@ module Linguist
     end
 
     disambiguate "IDL", "Prolog", "INI", "QMake" do |data|
-      if data.include?(":-")
+      if /^[^#]+:-/.match(data)
         Language["Prolog"]
       elsif data.include?("last_client=")
         Language["INI"]
diff --git a/samples/Perl/exception_handler.pl b/samples/Perl/exception_handler.pl
new file mode 100644
index 00000000..14807ced
--- /dev/null
+++ b/samples/Perl/exception_handler.pl
@@ -0,0 +1,117 @@
+package exception_handler;
+use sigtrap qw(die normal-signals);
+use IO::Handle;
+use Carp;
+use File::Spec;
+use File::Basename;
+use Data::Dumper;
+
+use sigtrap 'handler', \&tm_die;
+
+$Carp::CarpLevel = 1;     # How many extra package levels to skip on carp.
+
+BEGIN {
+    *CORE::GLOBAL::die = \&tm_die;
+    $main::SIG{__DIE__} = \&tm_die;
+    my $error_fd = $ENV{"TM_ERROR_FD"};
+	open (TM_ERROR_FD, ">&=$error_fd");
+	TM_ERROR_FD->autoflush(1);
+}
+
+sub realwarn { CORE::warn(@_); }
+sub realdie { CORE::die(@_); }
+
+sub longmess {
+    my ($arg, @rest) = shift;
+    {
+        local $@;
+        # XXX fix require to not clear $@?
+        # don't use require unless we need to (for Safe compartments)
+        require Carp::Heavy unless $INC{"Carp/Heavy.pm"};
+    }
+    # Icky backwards compatibility wrapper. :-(
+    my $call_pack = caller();
+    if ($Internal{$call_pack} or $Carp::CarpInternal{$call_pack}) {
+      return longmess_heavy($arg, @rest);
+    }
+    else {
+      local $Carp::CarpLevel = $Carp::CarpLevel + 1;
+      return longmess_heavy($arg, @rest);
+    }
+}
+
+sub longmess_heavy {
+  return @_ if ref($_[0]); # don't break references as exceptions
+  my $i = Carp::long_error_loc();
+  my ($arg, @rest) = @_;
+  return ret_backtrace($i, $arg, @rest);
+}
+
+sub quote {
+	my $str = shift;
+	$str =~ s/([^A-Za-z0-9\/_.-])/sprintf("%%%02X", ord($1))/seg;
+	return $str;
+}
+
+sub url_and_display_name {
+	my $file = shift;
+	my $url = "";
+	my $display_name = "";
+	$display_name = basename($file);
+	$url = 'url=file://' . quote($file);
+	return ($url, $display_name);
+}
+
+# Returns a full stack backtrace starting from where it is
+# told.
+sub ret_backtrace { 
+  my ($i, $arg, @rest) = @_;
+  my $mess;
+  $i++;
+
+  my $tid_msg = '';
+  if (defined &Thread::tid) {
+    my $tid = Thread->self->tid;
+    $tid_msg = " thread $tid" if $tid;
+  }
+
+  my %i = Carp::caller_info($i);
+  $arg =~ s/\n/\
/g;
+  $i{sub} =~ s/tm_die/die/g;
+  $mess .= "
$arg
\n"; + $mess .= "\n"; + my ($url, $display_name) = url_and_display_name($i{file}); + $mess .= "
\n"; + while (my %i = Carp::caller_info(++$i)) { + ($url, $display_name) = url_and_display_name($i{file}); + $mess .= " $i{sub} in $display_name at line $i{line}$tid_msg \n"; + } + $mess .= " $i{sub} in $display_name at line $i{line}$tid_msg