在Emacs中正确格式化Perl开关语句

3

编辑: 阅读了回复后,我相信答案是“不要这样做”,因此我将一个适当的回复标记为官方答案。

有没有一种简单的方法让emacs显示像perldoc.perl.org的 switch页面那样的perl switch语句呢?

这是perldoc.perl.org上的格式:

use Switch;

switch ($val) {
    case 1          { print "number 1" }
    case "a"        { print "string a" }
    case [1..10,42] { print "number in list" }
    case (\@array)  { print "number in list" }
    case /\w+/      { print "pattern" }
    case qr/\w+/    { print "pattern" }
    case (\%hash)   { print "entry in hash" }
    case (\&sub)    { print "arg to subroutine" }
    else            { print "previous case not true" }
}

以下是在代码片段上运行M-x indent-region后中的格式:

use Switch;

switch ($val) {
  case 1                { print "number 1" }
    case "a"    { print "string a" }
      case [1..10,42]   { print "number in list" }
        case (\@array)  { print "number in list" }
  case /\w+/    { print "pattern" }
        case qr/\w+/    { print "pattern" }
        case (\%hash)   { print "entry in hash" }
        case (\&sub)    { print "arg to subroutine" }
        else            { print "previous case not true" }
    }

我有一种难以解释的冲动,想坚持使用if-elsif结构...
附注:我认为this描述了所需的过程,但似乎需要花费一些时间进行解析。
3个回答

4
抱歉,我无法帮助您解决emacs问题。不过,我建议您坚持使用原来的工具。
if ( condition ) {

}
elsif( other_condition ) {

}
else {

}

与其使用可怕的Switch.pm,更好的选择是使用Perl 5.10版本以上提供的功能强大的替代方法,它不依赖于源代码过滤器。请参考Nicholas Clark在perl5.porters组的留言,该组表示Switch将在下一个主要版本中从Perl核心发布中删除。

有关更多讨论,请参见PerlMonks

use feature "switch";

given($_) {
   when (/^abc/) { $abc = 1; }
   when (/^def/) { $def = 1; }
   when (/^xyz/) { $xyz = 1; }
   default { $nothing = 1; }
}

3
Switch.pm将被移除,因为已经将其作为given/when的本地实现。因此,您提到删除Switch是正确的,但是请用given/when来替换它,而不是使用Perl4结构。 :) - Randal Schwartz
@Randal 好的,说得对。但是我之前在早期版本中使用 Switch.pm 时遇到了很多麻烦,如果不使用5.10版本,我认为最好还是避免使用它。 - Sinan Ünür
谢谢你提醒我!我确实不知道 given/when 或 Switch.pm 的问题。这也为我节省了很多可能会出现的糟糕重构时间和精力。 - vlee
1
值得注意的是,cperl-mode比StackOverflow解析器更好地解析了给定/当时的结构 ;) - jrockway
cperl-mode 6.2以与switch/case相同的方式格式化给定/当,也不将它们突出显示为关键字。我猜那就在待办事项列表上了! - kbro

0
如果cperl没有正确格式化它,请尝试使用perltidy。
这是一个很棒的函数,可以在Emacs中运行当前区域的perltidy:
;; 运行perltidy的巧妙函数 (defun perltidy-region () "对当前区域运行perltidy。" (interactive) (save-excursion (shell-command-on-region (point) (mark) "perltidy -q" nil t)))

0

你考虑过使用调度表吗?就像马克·杰森·多米努斯在Higher-Order Perl?中所概述的那样。


没有,谢谢你的信息。我确实能看到调度表的用处,但这有点偏离问题的主题。 - vlee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接