为什么一个空的 ERB 文件会在 Ruby 1.8.7 中引起警告?

Why does an empty ERB file cause a warning in Ruby 1.8.7?

我明白以下警告的意思:

-:1: warning: useless use of a variable in void context

但我不明白为什么 Ruby 1.8.7 中的 ERB 生成的代码在 void 上下文中使用 _erbout 变量:

$ rvm use ruby 1.8.7
Using /Users/radeksimko/.rvm/gems/ruby-1.8.7-head
$ touch test.erb
$ erb -x test.erb
_erbout = ''; _erbout
$ erb -x test.erb | ruby -w
-:1: warning: useless use of a variable in void context

这在 ERB / Ruby 2.0.0+ 中不是问题,尽管 ERB 从模板生成代码的方式不同:

$ rvm use 2.0.0
Using /Users/radeksimko/.rvm/gems/ruby-2.0.0-p598
$ erb -x test.erb
#coding:ASCII-8BIT
_erbout = ''; _erbout.force_encoding(__ENCODING__)
$ erb -x test.erb | ruby -w
$

需要明确的是,这与 _(下划线)在 Ruby 版本之间处理变量名无关:

$ rvm use 2.0.0
Using /Users/radeksimko/.rvm/gems/ruby-2.0.0-p598
$ echo "erbout = ''; erbout" | ruby -w
-:1: warning: possibly useless use of a variable in void context
$ rvm use 1.8.7
Using /Users/radeksimko/.rvm/gems/ruby-1.8.7-head
$ echo "erbout = ''; erbout" | ruby -w
-:1: warning: useless use of a variable in void context

这是一个应该报告给 Ruby/ERB 核心的错误还是我只是误会了什么?

警告是由第二行引起的:

_erbout = '';_erbout

什么都不做(_erbout 是该范围内的局部变量),并且它所处的上下文不 return 该行的值(就像在最后一行一种方法)。

在 Ruby 2.0.0 中,这一行被替换为

_erbout = '';_erbout.force_encoding(__ENCODING__)

现在 ruby 不确定方法调用是否有任何副作用,因此不会引发警告。

您可以使用以下代码重现此内容:

useless.rb

def test_me
  unused = 1
  unused
  3
end

p test_me
$ ruby -w useless.rb
useless.rb:3: warning: possibly useless use of a variable in void context
3

所有这些都会发生,因为 erb -x 的输出本身不应该是 运行。 运行使用 ruby 脚本时,最后一行 而不是 用作 return 值,这与方法不同。

如果您将代码嵌入到程序中,并实际使用 _erbout,则不会显示警告。