ruby-on-rails - 为什么 `duplicable?` 是这样定义的?

标签 ruby-on-rails ruby

我在 Rails 源代码中遇到过这个:

class Object
  def duplicable?
    true
  end
end

class NilClass
  begin
    nil.dup
  rescue TypeError    
    def duplicable?
      false
    end
  end
end

使用此代码,即使从对象中删除了 dup,该对象也会以 true 响应 duplicable?

我认为它可以重写为更简单的代码,例如:

class Object
  def duplicable?
    repond_to?(:dup)
  end
end

使用 begin...rescue 定义 duplicable? 有什么好处?

最佳答案

What is the merit of defining duplicable? using begin...rescue?

2.4 之前的 Ruby 在尝试 nil.dup 时引发了类型错误:

$ rbenv local 2.3.0

$ ruby --version
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]

$ ruby -e 'p nil.dup'
-e:1:in `dup': can't dup NilClass (TypeError)
    from -e:1:in `<main>'

从 Ruby 2.4 开始,nil.dup只是返回自己:

$ rbenv local 2.4.0

$ ruby --version
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin15]

$ ruby -e 'p nil.dup'
nil

将方法定义放在 rescue 中确保只为引发 TypeError 的 Ruby 版本定义该方法.

I think it can be rewritten to a simpler code like: [...]

简单检查接收者是否响应dup不起作用,因为 nil – 作为 Object确实回应dup ,即使在 2.3 中。 TypeError是(被)从Object#dup内部提出的:

VALUE rb_obj_dup(VALUE obj)
{
    VALUE dup;

    if (rb_special_const_p(obj)) {
        rb_raise(rb_eTypeError, "can't dup %s", rb_obj_classname(obj));
    }
    // ...
}

关于ruby-on-rails - 为什么 `duplicable?` 是这样定义的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49321553/

相关文章:

ruby-on-rails - 警告 : Use strings for Figaro configuration in rails migration

ruby-on-rails - rake 中止!未定义的方法 `each' 为零 :NilClass

ruby-on-rails - 在 rails 中使用带有删除操作的 link_to

css - 在 ruby​​ on rails 中将元素类拆分为两个类 html.slim

Ruby 在 n *milli* 秒后超时一段代码

ruby - 如何在 Ruby 中使实例变量私有(private)化?

ruby-on-rails - 列出一个国家的时区

ruby-on-rails - 用于解析 .doc 文件的 Ruby 库?

ruby - 如何在 debian lenny 上安装 ruby​​ 1.9.2?

Windows 上 Chocolatey 下的 Ruby 和 Ruby Dev