ruby - 我如何在 Ruby 中延迟评估尚未声明的类?

标签 ruby

或者,更确切地说,我该如何完美地做到这一点?

这是我到目前为止想出的:

# A double that stands in for a yet-to-be-defined class. Otherwise
# known as "lazy evaluation."
#
# Idea lifted from:
# http://github.com/soveran/ohm/
class Double < BasicObject
  def initialize(name)
    @name = name
  end

  def to_s
    @name.to_s
  end

  alias_method :inspect, :to_s

  def method_missing(mth, *args, &block)
    @unwrapped ? super : @unwrapped = true
    ::Kernel.const_get(@name).send(mth, *args, &block)
  ensure
    @unwrapped = false
  end; private :method_missing
end

这个有效:

foo = Double(:Foo)  # Now we can safely pass around Foo without 
                    # having initialised it.
foo.class           # Uninitialised constant
                    # That's expected because Foo doesn't exist yet!
class Foo; end      # So there, we shoo it into existence.
foo.class # Foo     # foo indeed is Foo. The sleight of hand of works.

这是我无法开始工作的原因:

inst = Foo.new
inst.is_a? Foo      # true, of course
inst.is_a? foo      # TypeError: class or module required

为什么不在最后一行中使用 double 代替 Foo?

最佳答案

您的代码没有任何问题 - 这是预期的行为。 #is_a?方法需要一个类或模块。尝试使用内置类,你会得到同样的错误:

str = "a string"
str.is_a? String
=> true

other_str = "another string"
str.is_a? other_str
=> TypeError: class or module required

如果你想改变你必须覆盖 is_a? (不会推荐)。更有可能的是,您想做这样的事情:

str.is_a? other_str.class
=> true

关于ruby - 我如何在 Ruby 中延迟评估尚未声明的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7393379/

相关文章:

ruby - Rake 不知道如何构建任务 : default or minitest

ruby - 帮助一个简单的方法

ruby - ruby 中 "&: "运算符的功能是什么?

ruby - 按月和年将 Ruby 日期数组分组为哈希

ruby-on-rails - Ruby 的自动代码健全性检查工具

ruby-on-rails - Rails 无法识别 lib 文件?

ruby - 如何基于 ruby​​ 中的相同键合并散列数组?

ruby-on-rails - 评论部分将最新评论排序在顶部而不是底部

ruby-on-rails - Rails : Math not computing correctly. 它关闭了 .00000000000001

ruby - 使用 session 时,Sinatra 应用程序在生产/测试环境中严重失败