Ruby 命名空间与顶级方法冲突

Ruby 命名空间与顶级方法冲突,ruby,Ruby,我有以下Ruby命名空间问题: 我在“库”中有许多顶级方法,其中我有一个get_name(param)方法。 问题是我想在一个拥有自己的get_name()方法(不带param!)的类中使用这个get_name(param)方法。 当然,这会导致一个问题,因为这两个方法不同,类中的新方法会覆盖顶级方法 有没有办法做到这一点: def get_name(param) puts param end class Foo def get_name() puts "name" en

我有以下Ruby命名空间问题:

我在“库”中有许多顶级方法,其中我有一个get_name(param)方法。 问题是我想在一个拥有自己的get_name()方法(不带param!)的类中使用这个get_name(param)方法。 当然,这会导致一个问题,因为这两个方法不同,类中的新方法会覆盖顶级方法

有没有办法做到这一点:

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
class Foo
  def get_name(*args)
    return super if args.any?
    puts 'name'
  end
end

我想知道是否有一种简单的方法可以实现这一点,而不必更改顶级方法的名称或范围。(我们的目标是使那些不经修改就可用的方法成为全局方法,但仍然能够无错误地调用Foo的实例方法。

如果库方法实际上是顶级方法,并且不是任何类或模块的一部分,那么它们将被定义为
对象的
私有
方法

您可以执行以下操作来调用它:

  def bar()
    self.get_name()
    Object.send(:get_name, "abc")  # Will print "abc" to console
  end
所谓的“顶级方法”只是
main
对象的方法,它只是
对象
。如果您希望该方法能够(几乎)在任何地方被调用,您应该将其设置为内核方法

module Kernel
  def get_name(param)
    puts param
  end
end
请注意,
Kernel
几乎位于任何类祖先链的尾部(在
BasicObject
之前),这意味着几乎所有对象都是
Kernel
。因此,在
Foo
类中,您可以这样覆盖它:

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
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

首先:没有所谓的“顶级方法”,Ruby中只有一种方法:实例方法

您所指的方法是
对象
私有
实例方法。因为
对象
几乎是任何其他类的超类(不包括
对象
及其超类),如果您确定在继承层次结构的其他地方没有其他同名方法,则可以使用
Method\super\u 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
或者,如果您不知道继承层次结构中是否存在同名的任何其他方法,则可以直接从
对象
获取对
未绑定方法
的引用,然后
绑定
调用
它:

class Foo 
  def bar
    get_name #should work and print name, i.e. it uses the get_name method of Foo
    Object.instance_method(:get_name).bind(self).('abc') #should work and print abc, i.e. it uses the top-level method
  end
end

Foo.new.bar
# name
# abc

可能有帮助我的建议:只需在顶层创建别名。别名不会修改其前映像;-)这没有意义。顶级的
get\u name
方法是一个实例方法,但是您试图在
Foo
实例上调用它。