覆盖变量而不重复名称

时间:2016-09-18 12:44:13

标签: ruby performance

是否有方法可以在不复制名称的情况下覆盖变量?例如,当我想将my_var = '3'更改为整数时,我必须执行以下操作:

my_var = my_var.to_i

有没有办法在不复制变量名的情况下这样做?我想做这样的事情:

my_var = something_const.to_i

对于数字,存在+=-=等,但是对于所有方法都有通用的方法吗?

1 个答案:

答案 0 :(得分:4)

没有办法将字符串转换为这样的整数,而不重复变量名。诸如String#upcase!Array#flatten!之类的方法可以通过变异对象来完成;但是,无法定义像String#to_i!这样的方法,因为我们正在将对象转换为不同类的实例。

例如,这是一个(失败的)尝试定义这样的方法:

# What I want to be able to do:
# my_var = "123"
# my_var.to_i! # => my_var == 123

class String
  def to_i!
    replace(Integer(self))
  end
end

my_var = "123"
my_var.to_i! # TypeError: no implicit conversion of Fixnum into String

...即使这段代码有效,它仍然不会提供任何性能提升,因为仍在创建一个新对象。

至于您+=-=的示例,这些实际上只是简写:

x += 1
# Is equivalent to:
x = x + 1

再次,这里也没有性能增益;只是稍微好一点的语法。一个很好的问题是,why doesn't ruby support a ++ operator?如果这样的运算符存在,那么提供性能提升......但是我会让你自己研究为什么语言中缺少这个。

总结一下,

  

是否有通用的方法为所有方法执行此操作?

没有。 +=-=|=&=等特殊运算符都是预定义的;没有“通用”版本,例如method_name=

您还可以定义改变对象的方法,但仅限于适当的时候。这种方法通常用!命名,称为“爆炸方法”,并且具有“非爆炸”对应物。例如,在String个对象上,有String#capitalize!(和String#capitalize),String#delete!(和String#delete),String#encode!(和{{ 1}}),....但由于上述原因,没有String#encode