或者说,我该如何完美地完成它?
这是我到目前为止所提出的:
# 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
为什么最后一行的Foo不会代表Foo?
答案 0 :(得分:4)
您的代码没有任何问题 - 这是预期的行为。 #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
答案 1 :(得分:0)
如果您希望foo
成为班级Foo
:
foo = Foo
inst = Foo.new
inst.is_a? foo #=> true
inst2 = foo.new
inst2.is_a? Foo #=> true
答案 2 :(得分:0)
如果您在模块中的类中定义了所需的行为,那该怎么办?
或者将课程包装在模块中?