我有以下Ruby命名空间问题:
我在"库"中有许多顶级方法,其中我有一个get_name(param)方法。 问题是我想在具有自己的get_name()方法的类中使用这个get_name(param)方法(没有param!)。 当然这会导致问题,因为2种方法不同,而且班级中的新方法会覆盖顶级方法。
有没有办法做这样的事情:
def get_name(param)
puts param
end
class Foo
def get_name()
puts "name"
end
def bar()
self.get_name() #should work and print name, i.e. it uses the get_name method of Foo
get_name("abc") #should work and print abc, i.e. it uses the top-level method
end
end
我想知道是否有一种简单的方法可以实现这一点,而无需更改顶级方法的名称或范围。 (目标是将这些可用而不作为全局方法进行修改,但仍然能够无错误地调用Foo的实例方法。
答案 0 :(得分:2)
如果库方法确实是顶级方法,并且不属于任何类或模块,那么它们将被定义为private
类的Object
方法。
您可以执行以下操作来调用它:
def bar()
self.get_name()
Object.send(:get_name, "abc") # Will print "abc" to console
end
答案 1 :(得分:0)
所谓的“顶级方法”只是main
对象的一种方法,它只是Object
。如果您希望能够(几乎)在任何地方调用该方法,则应将其设为内核方法。
module Kernel
def get_name(param)
puts param
end
end
请注意,Kernel
几乎位于祖先链的任何类的尾部(BasicObject
之前),这意味着几乎所有对象都是Kernel
。因此,在Foo
课程中,您可以像这样覆盖它:
class Foo
def get_name(*args)
return super if args.any?
puts 'name'
end
end
如果你不能制作那些顶级方法的内核方法,你可以将main
对象存储在常量或全局变量中,并在其上调用那些顶级方法。
$main = self
class Foo
def get_name(*args)
return $main.send(:get_name, *args) if args.any?
puts 'name'
end
end
答案 2 :(得分:0)
首先:没有“顶级方法”这样的东西。 Ruby中只有一种方法:实例方法。
您指的方法是private
Object
实例方法。由于Object
是几乎所有其他类的超类(不包括Object
及其超类),如果您确定在继承层次结构中的其他位置没有其他同名的方法,则可以使用Method#super_method
访问该方法然后调用它:
def get_name(param)
puts param
end
class Foo
def get_name
puts 'name'
end
def bar
get_name #should work and print name, i.e. it uses the get_name method of Foo
method(:get_name).super_method.('abc') #should work and print abc, i.e. it uses the top-level method
end
end
Foo.new.bar
# name
# abc
或者,如果不知道继承层次结构中是否存在同名的其他方法,则可以获取对{{1直接来自UnboundMethod
然后Object
和bind
:
call