我正在寻找一种处理以下情况的简洁方法:给定一个变量(实际上,它是一个类中的实例变量,尽管我认为这并不重要),已知为{{ 1}}或按住nil
。如果它是整数,则该变量应递增。如果为nil,则应使用Integer
进行初始化。
这些显然是解决方案,将1
作为要处理的变量:
@counter
或
# Separate the cases into two statements
@counter ||= 0
@counter += 1
我不喜欢这些解决方案,因为它们需要重复变量的名称。以下尝试失败:
# Separate the cases into one conditional
@counter = @counter ? (@counter + 1) : 1
这不能完成,因为赋值运算符的结果不是左值,尽管实际的错误消息有些晦涩。在这种情况下,您会收到错误_unexpected tOP_ASGN,并期望end _。
是否有一个很好的成语来编写我的问题,还是我必须坚持我笨拙的解决方案之一?
答案 0 :(得分:2)
问题很明显:
nil
或整数。如果将nil
设置为等于1
,则将变量设置为等于其值加上1
。首先,有两点。
1
进行初始化。”。这与已知该变量为nil
或整数的说法相矛盾,这意味着该变量已被初始化,或更准确地说是 defined 。对于实例变量,这种区别是不相关的,因为当Ruby将未定义的实例变量引用为rvalues时,它们会将它们初始化为nil
。这是局部变量的重要区别,但是,当将未定义的局部变量引用为右值时会引发异常。nil
或integer
以外的对象的情况。因此,它们无关紧要。如果OP希望扩大问题范围,以允许变量保存nil
或整数(例如,数组或哈希)以外的对象,则应询问一个单独的问题。在确定最佳代码时应使用什么标准?在提到的各种可能性中,我看不到效率方面的重要差异。假设情况如此,或者相对效率在应用程序中不重要,我们将可读性(以及扩展性,可维护性)作为唯一标准。如果x
等于nil
或整数,或者是未定义的实例变量,则也许最清晰的代码如下:
x = 0 if x.nil?
x += 1
或
x = x.nil? ? 1 : x+1
几乎不那么可读:
x = (x || 0) + 1
及其后一步:
x = x.to_i + 1
这要求读者知道nil.to_i #=> 0
。
OP可能认为这些解决方案“笨拙”,但我认为它们都很漂亮。
是否可以编写引用x
但一次的表达式?我想不出一种方法,评论中也没有提出任何建议,因此,如果有一种方法(我认为是可疑的),可能就无法通过可读性测试。
现在考虑未定义局部变量x
的情况。在这种情况下,我们可以这样写:
x = (defined?(x) ? (x || 0) : 0) + 1
defined?是Ruby关键字。