我可以在Ruby的下一行添加if / unless子句吗?

时间:2015-02-11 13:10:30

标签: ruby conditional-statements

在Perl中,我经常发现自己使用以下模式:

croak "incompatible object given: $object"
    unless $object->isa('ExampleObject') and $object->can('foo');

我试着把它翻译成Ruby,就像这样:

raise ArgumentError, "incompatible object given: #{object.inspect}"
    unless object.is_a?(ExampleObject) and object.respond_to?(:foo)

但这不起作用,因为Ruby将unless解释为新语句的开头。据我所知,我可以在第一行的末尾添加一个反斜杠,但这看起来很难看并且感觉不对。我也可以使用常规的unless condition raise error end结构,但我更喜欢原始形式的风格。有没有一种很好的(和惯用的)方法将它写成Ruby中的单个语句?

4 个答案:

答案 0 :(得分:5)

  

我可以在Ruby的下一行添加if / unless子句吗?

你做不到。来自final draft of ISO Ruby的第107页(PDF页面127)通常不相关,但这样的基本内容也使我们不必阅读parse.y

unless-modifier-statement ::
    statement [no line-terminator here] unless expression

这很清楚。它只是与你的Perl示例相似而不是:

raise ArgumentError, "incompatible object given: #{object.inspect}" unless
  object.is_a?(ExampleObject) and object.respond_to?(:foo)`

或:

raise ArgumentError, "incompatible object given: #{object.inspect}" \
  unless object.is_a?(ExampleObject) and object.respond_to?(:foo)

答案 1 :(得分:2)

正如你在最后添加反斜杠以强制使用单行语句一样错误,当它超出一行时使用单行语句是错误的。

答案 2 :(得分:1)

这不是一个真正的解决方案,在阅读这个问题时我很草率。 OP想要一个没有反斜杠的解决方案。

你应该可以这样做:

raise ArgumentError, "incompatible object given: #{object.inspect}" \
  unless object.is_a?(ExampleObject) and object.respond_to?(:foo)

\个字符告诉ruby继续阅读,好像没有换行符一样。

答案 3 :(得分:-1)

据我所知,除了\之外别无他法,因为正如你已经说过的那样,Ruby认为这是一个新陈述。

请记住,样式指南和约定因语言而异。在Ruby中,我不希望在它的代码之后出现if / unless语句。事实上,我甚至不喜欢将if/unless放在一行的末尾,因为它会将阅读方向从If this, then that反转为that, if this (then what? Ah, I need to read back again),尤其是当条件比raise 'foo' if bar.empty?更复杂时

在Perl和其他语言中,虽然这可能有所不同,因为你有其他约定,样式指南和这个; - thingy;)