是否有可能ruby模块获取定义包含该模块的类的文件的目录?

时间:2010-08-05 16:21:11

标签: ruby directory module

我有一个模块和一个包含该模块的类。这些未在同一文件中定义,或在同一文件夹中定义。我希望模块获取定义类的目录。

# ./modules/foo.rb
module Foo
  def self.included(obj)
    obj_dirname = # ??? what goes here?
    puts "the class that included Foo was defined in this directory: #{obj_dirname}"
  end
end

# ./bar.rb
class Bar
  include Foo
end

我希望这个输出是:

the class that included Foo was defined in this directory: ../
这可能吗?如果是这样,怎么样?

4 个答案:

答案 0 :(得分:3)

可以在许多文件中定义类,因此对您的问题没有真正的答案。另一方面,您可以判断include Foo来自哪个文件:

# ./modules/foo.rb
module Foo
  def self.included(obj)
    path, = caller[0].partition(":")
    puts "the module Foo was included from this file: #{path}"
  end
end

这将是您正在寻找的路径,除非在其他地方有MyClass.send :include, Foo,然后定义MyClass ...

注意:对于Ruby 1.8.6,require 'backports'或将partition更改为其他内容。

答案 1 :(得分:2)

没有内置的方法可以找出模块或类的定义位置(afaik)。在Ruby中,您可以随时随地重新打开模块/类,并添加或更改行为。这意味着,通常没有单独的地方定义模块/类,这样的方法没有意义。

在您的应用程序中,您可以坚持一些约定,以便您能够构造源文件名。例如。在Rails中,页面控制器按照惯例命名为PagesController,主要在app / controllers / pages_controller.rb文件中定义。

答案 2 :(得分:0)

这样做你想要的吗?

module Foo
  def self.included(obj)
    obj_dirname = File.expand_path(File.dirname($0)) 
    puts "the class that included Foo was defined in this directory: #{obj_dirname}"
  end
end

编辑:根据评论进行更改。

答案 3 :(得分:0)

module Foo

  def self.included obj
    filename = obj.instance_eval '__FILE__'
    dirname = File.expand_path(File.dirname(filename))
    puts "the class that included Foo was defined in this directory: #{dirname}"
  end

end