我试图找出的是,是否存在某种与我在groovy中看到的ExpandoMetaClasses等价的东西。我一直在读关于Open Classes的文章,但是我不太明白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,那么只会影响该模块,或者我包含的gem中的任何.rb文件都会受到影响吗?
为在Ruby和Groovy上做出一些可能的假设而预先道歉,我对两者都不熟悉,但一直在试图找到两者之间的等价性。
最佳答案
ruby的类永远不会“关闭”。所以当你说:
class String
def omg!
self.replace "OMG"
end
end
您正在String类上定义
omg!
方法与groovy中需要使用特殊的元类概念不同,ruby类总是开放的,句点。如果要修改特定的字符串集,可以执行以下操作:
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
实际上,模块是可以添加到类或特定实例中的方法的集合。
因此,您可以直接打开一个类,也可以使用模块向类添加新方法。也可以直接打开实例或使用模块向实例添加新方法那是因为一个类只是类的一个实例;)相当漂亮!
关于ruby - Ruby中的Open类作用域与Groovy中的MOP作用域,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1061908/