我想弄清楚的是,我在Groovy中看到的ExpandoMetaClasses是否有某种等价性。我一直在阅读关于开放班的文章,但我不太清楚Ruby的作用域允许对类进行多大程度的修改。
借用上面博客中的一个例子,在Groovy中,我可以修改Java的String类,并向其添加如下方法:
String.metaClass.shout = {->
return delegate.toUpperCase()
}
println "Hello MetaProgramming".shout()
// output
// HELLO METAPROGRAMMING我认为Ruby会让您重新定义类并可能将其化名(请帮助澄清我在这一点上的误解):
class String
def foo
"foo"
end
end
puts "".foo # prints "foo"在Groovy中,有一些方法可以将核心Java库方法的重新定义扩展到单个实例或使用类别的一组实例,这与我在Ruby中定义的混合器类似。
对特定实例或模块子集进行开放类范围的方法是什么?
如果我要安装一个重新定义了某个核心类的gem,那么该模块是否会受到影响,或者我所包含的任何.rb文件都会受到影响?
对于在Ruby和Groovy上做出一些可能的假设,我事先表示歉意,我对两者都很陌生,但我一直在试图找到两者之间的等价性。
发布于 2009-06-30 07:00:01
Ruby的类从未“关闭”过。所以当你说:
class String
def omg!
self.replace "OMG"
end
end在String类上定义omg!方法。与Groovy不同,Groovy需要使用特殊的元类概念,Ruby类始终是开放的。
如果您想要修改一组特定的String,可以这样做:
module Magic
def presto
puts "OMG A HAT!"
end
end
class Array
include Magic
end
x = "Hello".extend(Magic)
puts x #=> Hello
x.presto #=> OMG A HAT!
[].presto #=> OMG A HAT!
def x.really?
true
end
x.really? #=> true实际上,模块是可以添加到类或特定实例中的方法的集合。
因此,您可以直接打开类,也可以使用模块向类添加新方法。还可以使用模块直接打开实例或向实例添加新方法。那是因为一个类只是类的一个实例;)相当漂亮!
发布于 2009-06-30 07:32:55
除了Yehuda所说的,Ruby中的实例也有元类(技术上称为“单例类”),可以用class <<whatever访问。例如,要用单例类重做Yehuda的魔法示例:
x = "Hello"
class <<x
include Magic
def magical?
true
end
end
x.presto #=> OMG A HAT!
x.magical? #=> true
"Something else".magical? #=> NoMethodError发布于 2009-06-30 16:01:55
没有对类进行修改的范围。一旦修改了类,所有后续的require和下面的代码都可以访问修改后的类。
https://stackoverflow.com/questions/1061908
复制相似问题