在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中的单个语句?
答案 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;)