Tập lệnh perl này thực hiện công việc hack tại đó, đưa ra một số giả định về cấu trúc tệp nguồn. (Chẳng hạn như: .hs
tệp (không phải .lhs
), chữ ký nằm trên dòng ngay trước định nghĩa, định nghĩa tuôn ra ở lề trái, vv)
Nó cố xử lý (bỏ qua) nhận xét, định nghĩa kiểu phương trình (với lặp lại bên trái) và các loại tạo ra đầu ra nhiều dòng trong ghci
.
Không nghi ngờ gì, nhiều trường hợp hợp lệ thú vị không được xử lý đúng cách. Kịch bản không gần với việc tôn trọng cú pháp thực tế của Haskell.
Nó cực kỳ chậm, vì nó khởi chạy phiên ghci
cho mỗi chức năng cần chữ ký. Nó tạo một tệp sao lưu File.hs.bak
, in các hàm mà nó tìm thấy thành tiêu chuẩn, cũng như chữ ký cho các hàm thiếu chữ ký và viết mã nguồn được nâng cấp lên File.hs
. Nó sử dụng một tệp trung gian File.hs.new
và có một vài kiểm tra an toàn để tránh ghi đè nội dung của bạn bằng rác.
SỬ DỤNG RỦI RO RIÊNG CỦA BẠN.
Tập lệnh này có thể định dạng ổ cứng của bạn, đốt cháy ngôi nhà của bạn, không an toànPerformIO và có các tác dụng phụ không tinh khiết khác. Trong thực tế, nó có thể sẽ.
Tôi cảm thấy rất bẩn.
Được thử nghiệm trên Mac OS X 10.6 Snow Leopard với một vài tệp nguồn của riêng tôi .hs
.
#!/usr/bin/env perl
use warnings;
use strict;
my $sig=0;
my $file;
my %funcs_seen =();
my %keywords =();
for my $kw qw(type newtype data class) { $keywords{$kw} = 1;}
foreach $file (@ARGV)
{
if ($file =~ /\.lhs$/)
{
print STDERR "$file: .lhs is not supported. Skipping.";
next;
}
if ($file !~ /\.hs$/)
{
print STDERR "$file is not a .hs file. Skipping.";
next;
}
my $ghciPreTest = `echo 1 | ghci $file`;
if ($ghciPreTest !~ /Ok, modules loaded: /)
{
print STDERR $ghciPreTest;
print STDERR "$file is not valid Haskell source file. Skipping.";
next;
}
my $module = $file;
$module =~ s/\.hs$//;
my $backup = "$file.bak";
my $new = "$module.New.hs";
-e $backup and die "Backup $backup file exists. Refusing to overwrite. Quitting";
open OLD, $file;
open NEW, ">$new";
print STDERR "Functions in $file:\n";
my $block_comment = 0;
while (<OLD>)
{
my $original_line = $_;
my $line = $_;
my $skip = 0;
$line =~ s/--.*//;
if ($line =~ /{-/) { $block_comment = 1;} # start block comment
$line =~ s/{-.*//;
if ($block_comment and $line =~ /-}/) { $block_comment=0; $skip=1} # end block comment
if ($line =~ /^ *$/) { $skip=1; } # comment/blank
if ($block_comment) { $skip = 1};
if (!$skip)
{
if (/^(('|\w)+)(+(('|\w)+))* *=/)
{
my $object = $1;
if ((! $keywords{$object}) and !($funcs_seen{$object}))
{
$funcs_seen{$object} = 1;
print STDERR "$object\n";
my $dec=`echo ":t $1" | ghci $file | grep -A100 "^[^>]*$module>" | grep -v "Leaving GHCi\." | sed -e "s/^[^>]*$module> //"`;
unless ($sig)
{
print NEW $dec;
print STDERR $dec;
}
}
}
$sig = /^(('|\w)+) *::/;
}
print NEW $original_line;
}
close OLD;
close NEW;
my $ghciPostTest = `echo 1 | ghci $new`;
if ($ghciPostTest !~ /Ok, modules loaded: /)
{
print $ghciPostTest;
print STDERR "$new is not valid Haskell source file. Will not replace original (but you might find it useful)";
next;
} else {
rename ($file, $backup) or die "Could not make backup of $file -> $backup";
rename ($new, $file) or die "Could not make new file $new";
}
}
Lệnh 'lệnh hs-lint' trong Emacs sẽ tự động áp dụng các gợi ý nếu 'hs-lint-replace-without-ask' được đặt thành' t'. Tôi không chắc chắn làm thế nào để hạn chế nó để chỉ cần gõ chữ ký, nhưng chắc chắn phải có một cách. Và tôi chỉ đăng nhận xét này vì nhận xét vì nó không phải là giải pháp EclipseFP. –