【问题标题】:Strange result in Ruby with "end if"Ruby中带有“end if”的奇怪结果
【发布时间】:2015-08-21 07:36:23
【问题描述】:

我希望这段代码执行代码块并导致输出"x""y",或者只是抛出一个语法错误:

if true
  puts "x"
end if
puts "y"

但是,解释器会忽略if true 块,只执行puts "y"。如果我改为输入以下代码:

if true
  puts "x"
end if

解释器以输入结束语法错误退出。第一个 sn-p 是有效代码但不知何故执行错误有什么原因吗?在我看来,解析器中有一些错误。

我已经在 Ruby 2.1.2 和 Ruby 2.1.5 中确认了这一点。

【问题讨论】:

  • 你的代码相当于if puts "y"; if true; puts "x"; end; endputs "y" 返回nil,所以if true; puts "x"; end 不会被执行。
  • 啊啊啊,我明白了。它像单线一样执行。 (如果为真; puts "x"; end) if puts "y" 有点棘手。没想到它会这样读。
  • 尝试使用Ruby parser,看看它是否可以解释您的代码是如何被解释的。

标签: ruby


【解决方案1】:

这里有两件事一起玩:

  1. puts的返回值为nil
  2. 如果当前命令尚未结束,Ruby 通常足够聪明地读取下一行。

这意味着:

if true
  puts "x"
end if
puts "y"

等于:

if true
  puts "x"
end if (puts "y")

Ruby 将 puts "y" 评估为 nil:

if true
  puts "x"
end if nil

是什么导致 Ruby 不评估 if true 块,因为 if nil 的行为类似于 if false


或者换句话说:你的例子是一样的:

if puts("y") # evaluates to nil (aka is falsey)
  if true
    puts "x"
  end 
end

【讨论】:

  • 但是 end 语句不应该结束第一个 if 语句吗?它是否以某种方式作为“与”语句执行?
  • end 结束第一个 if 语句。但是ifend 在同一行中的工作方式与您可能看到的普通modifing if 一样(类似这样的单行:do_foo if bar?)。
【解决方案2】:

我想你的意思是

if true
  puts "x"
end 
puts "y"

这将产生您期望的输出。

【讨论】:

  • 你为什么认为这就是 OP 的意图?
  • 因为他说他期望原始代码输出x和y。
  • 他可能已经预料到了,因为他认为puts "y" 返回了一个真实的值。这两种解释都是合理的。
【解决方案3】:

您的代码不正确。正确的代码是:

if true
  puts "x"
end
puts "y"

如果puts "y" 返回true,您的代码会告诉Ruby 执行if true ... end blockputs 返回 nil,在条件检查中等于 false,导致该块根本没有被执行。

【讨论】:

  • 语法没有错。这是一种常用的语法。
  • 你是对的。从提问者的角度来看,我的意思是不正确的。
  • 你是对的。我忘记了自己,以为我在写 VB 脚本;)
  • @user5248817 发生在我们最好的人身上。 :)
【解决方案4】:

您的代码实际上是在说仅当 puts "y" 返回 true 时才执行 if true 块。不幸的是,puts 返回 nil。要在 Ruby 中结束 if 语句,您只需使用 end。与 Shell Scripting 或 Visual Basic 不同,不同的块没有特定的结束语句。

改变

if true
  puts "x"
end if
puts "y"

if true
  puts "x"
end
puts "y"

你会是金色的。

【讨论】:

    猜你喜欢
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多