是有一个简单的方法来测试对象是否是不可改变的(人数、零)或不(阵列,散列,目的)?换句话说,它可能改变的副作用从其他代码?

动机:我想创建一个版本的价值储存,但某些数据组。一些阵列会商定的对象,而且我可以颠倒的关系通过储存的'在'财产,并寻找它。但我也想以能够存储阵列的符号,其他阵列,等等。

有帮助吗?

解决方案

有没有原始的对象在红宝石。这可能因此不能检测到一个简单的方式。

你不能简单地使用的元帅或其为你的版本控制的商店?然后你会得到装载和保存所有类型的对象是免费的。为什么要重新发明轮子呢?

我不知道你想达到什么确切的,但看来源,其可能有兴趣看看他们是如何处理这个问题。Ruby其编码的实施只是实现了 to_yaml 方法对所有相关的课程。看看 其/rubytypes.rb.

其他提示

,我发现一种低效的方法:

class Object
  def primitive?
    begin
      self.dup
      false
    rescue TypeError
      true
    end
  end
end

可变性的想法不一样的方式真正适用于红宝石在其他语言。唯一不变的对象是冻结的。您甚至可以添加方法和实例变量Fixnums。例如:

class Fixnum
  attr_accessor :name
end
1.name = "one"
2.name = "two"

显然,绝大多数的时候,人们是不会有足够的病理将属性添加到Fixnum对象,但问题是,没有解冻对象是真的不可改变的。

如果你能拿出你不想承担是不可改变的班cannonical列表,你可以只办理,并给他们所有返回true的immutable?()方法(和对象返回false一个版本)。与元帅但像wvanbergen说,以确保您的目标不会改变的副本是最好的方式深复制它。

另一个区别:本身不可变对象不能被冻结,但他们仍从冷冻返回false

5.freeze.frozen? == false

冻结不引发异常(不像DUP)然而它确实(永久!)修改可变对象。

我发现我可以(至少在它的当前状态)安排我的应用程序冻结对象的工作,和红宝石会给我一个异常,如果我尝试直接修改它们。然而的冷冻仅影响存储在它仍然可以修改的对象,然后阵列等的第一级。

这仅适用于1.8 - 5.frozen?在ruby1.9返回true(但不是在irb1.9)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top