Ruby中的Open类与Groovy中的MOP的作用域

Nic*_*uer 1 ruby groovy metaprogramming

我想要弄清楚的是,我在Groovy中看到的是否与ExpandoMetaClasses有某种等价.我一直在阅读有关Open Classes的内容,但我无法确定Ruby允许类修改的范围.

借用上面博客中的一个例子,在Groovy中,我可以修改Java的String类并向它添加一个方法,如下所示:

String.metaClass.shout = {->
  return delegate.toUpperCase()
}

println "Hello MetaProgramming".shout()

// output
// HELLO METAPROGRAMMING
Run Code Online (Sandbox Code Playgroud)

而且我认为 Ruby会让你重新定义这个类并且可能是别名(请帮助澄清我此时的误解):

class String
  def foo
    "foo"
  end
end 

puts "".foo # prints "foo"
Run Code Online (Sandbox Code Playgroud)

在Groovy中,有一些方法可以将核心Java库方法重新定义为单个实例或使用Categories的一组实例,这些方法与我在Ruby中定义为mixins的方式类似.

将开放类的范围扩展到特定实例或模块子集的方法有哪些?

如果我要安装一个已重新定义某个核心类的gem,那么只会影响该模块,或者是否会将任何.rb文件包含在受该影响的gem中?

为Ruby和Groovy做出一些可能的假设提前道歉,我对两者都很新,但一直试图找到两者之间的等价.

Yeh*_*atz 5

Ruby的类永远不会"关闭".所以当你说:

class String
  def omg!
    self.replace "OMG"
  end
end
Run Code Online (Sandbox Code Playgroud)

您正在omg!String类上定义方法.与需要使用特殊元类概念的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
Run Code Online (Sandbox Code Playgroud)

实际上,模块是可以添加到类或特定实例的方法的集合.

因此,您可以直接打开一个类,也可以使用模块向类中添加新方法.您还可以直接打开实例或使用模块向实例添加新方法.那是因为一个类只是Class的一个实例;)非常漂亮!