【问题标题】:Unindenting multiline string literals取消缩进多行字符串文字
【发布时间】:2014-02-19 06:43:14
【问题描述】:

在 Perl 中,可以使用普通引号或 here-doc 语句编写多行字符串文字,但由于代码缩进被视为字符串本身的内容,这要么破坏了周围代码的格式,要么需要我们额外取消缩进使用前的字符串。此时,我使用以下子例程来取消缩进字符串文字:

sub unindent {
    local $_ = shift;
    $_ =~ s/^\s*$//mg;
    $_ =~ s/^(\s*>>>\s)//mg;
    return $_;
}

print unindent "
    >>> #pragma once
    >>> #include <...>
    >>> ";

但不是重新发明轮子,我想问一下 Perl 或 CPAN 中是否已经有为此目的内置的东西?

【问题讨论】:

  • 在子例程中使用全局默认变量$_ 不是一个好主意,因为它很容易创建一个词法变量,例如my $str = shift.
  • local $_ = shift
  • @TLP, @tobyink, ops,我忘了$_ 不会自动变成本地的。感谢您的指正!

标签: perl cpan multiline code-formatting literals


【解决方案1】:

经过一番谷歌搜索后,我发现了一些具有相似功能的软件包并部分解决了问题:

第一个选项需要安装很多依赖项(对于简单的unindent 函数),其余三个仅用于here-docs。这些包似乎都不支持额外的标记(问题中的&gt;&gt;&gt;),在我看来,这比普通缩进更安全(由于制表符空间混合问题)。

【讨论】:

  • 我真的很喜欢Heredoc::Unindent,但它只适用于在标识符后面带有分号的heredocs(例如&lt;&lt;END;)——通过将第56和70行替换为[,;\)] # semicolon (end of statement) or comma (end of hash value) or bracket (the substr(&lt;&lt;END,0,-1) construct removes the last newline)来调整它。
  • FWIW:强烈不鼓励在生产代码中使用源过滤器。
【解决方案2】:

这可能与其说是评论不如说是一个答案,但由于 cmets 中没有契约,我认为使用答案会更好地表达我的观点。 我估计你正在寻找一种方法来写类似的东西

my $str= "Stuff One
          Stuff Two
          Stuff Three";

因为它更具可读性但实际的字符串应该变成:

my $str= "Stuff OneStuff TwoStuff Three";

my $str=
"Stuff One
Stuff Two
Stuff Three";

对吗?我不知道清理字符串的模块,我相信由于使用了制表符或空格,它可能不是微不足道的,最后一部分之后是否应该有换行符或换行符?但是,您可以只写:

my $str= "Stuff One".
         "Stuff Two".
         "Stuff Three";

my $str= "Stuff One\n".
         "Stuff Two\n".
         "Stuff Three";

并完全控制字符串中的内容和不包含的内容,而不会弄乱代码契约或任何不需要的依赖项。

【讨论】:

  • 很明显. 运算符也可以用于形成多行字符串,但是必须引用每一行会产生很多视觉噪音。我的问题主要是您提到的第二种情况,保留了换行符,但有时拥有unindent() 函数的变体也可以删除换行符。
  • 好吧,但你必须记住哪个是做什么的。更重要的是,当有人阅读您的代码时,以我的方式,他们立即知道字符串的外观以及其中的内容和不包含的内容。如果省略引号和点,任何不熟悉字符串在几行之后的使用方式的人都会感到非常困惑。对我来说,一个看起来定义得很糟糕的字符串,我必须检查它是如何使用的,这不仅会打断我几个引号和点。更不用说unindent() 添加的单个字符比最多添加四行更多。
  • 最后,这如何比&gt;&gt;&gt;&gt; 添加更多的视觉噪音?几乎每个程序员,无论他们是否见过 Perl,都会理解引号和点的作用。但是除了你之外的每个人都会对&gt;&gt;&gt;&gt;在那里所做的事情感到困惑。
  • @DeVader:为每一行加上引号(和“\n”!)非常麻烦,对我来说看起来很糟糕。当然,&gt;&gt;&gt; 标记很长,我在挑选之前没有想太多,但可以放心地替换为,例如|。我希望这样的结构内置到语言本身中。
【解决方案3】:

You appear to want Syntax::Feature::Qi。就像 Python 的textwrap.dedent

奇怪的是,核心语言中没有这方面的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-05
    • 2011-03-22
    • 2011-01-31
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多