Ruby:成语“创建和增量”

时间:2019-08-21 10:48:55

标签: ruby

我正在寻找一种处理以下情况的简洁方法:给定一个变量(实际上,它是一个类中的实例变量,尽管我认为这并不重要),已知为{{ 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 _。

是否有一个很好的成语来编写我的问题,还是我必须坚持我笨拙的解决方案之一?

1 个答案:

答案 0 :(得分:2)

问题很明显:

  • 已知变量包含nil或整数。如果将nil设置为等于1,则将变量设置为等于其值加上1
  • 在Ruby中实现此功能的最佳方法是什么?

首先,有两点。

  • 问题指出:“如果为nil,则应使用1进行初始化。”。这与已知该变量为nil或整数的说法相矛盾,这意味着该变量已被初始化,或更准确地说是 defined 。对于实例变量,这种区别是不相关的,因为当Ruby将未定义的实例变量引用为rvalues时,它们会将它们初始化为nil。这是局部变量的重要区别,但是,当将未定义的局部变量引用为右值时会引发异常。
  • 注释在很大程度上解决了变量包含nilinteger以外的对象的情况。因此,它们无关紧要。如果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关键字。