简体   繁体   English

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

[英]is it possible for a ruby module to get the directory of the file that defined a class that included the module?

i've got a module and a class that includes the module. 我有一个模块和一个包含该模块的类。 these are not defined in the same file, or in the same folder. 这些未在同一文件中定义,或在同一文件夹中定义。 i want the module to get the directory that the class is defined in. 我希望模块获取定义类的目录。

# ./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

i would expect the output of this to be: 我希望这个输出是:

the class that included Foo was defined in this directory: ../

is this possible? 这可能吗? if so, how? 如果是这样,怎么样?

Classes can be defined in many files, so there is no real answer to your question. 可以在许多文件中定义类,因此对您的问题没有真正的答案。 On the other hand, you can tell from which file the include Foo was made: 另一方面,您可以告诉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

This will be the path you're looking for, unless there's a MyClass.send :include, Foo somewhere else then where MyClass was defined... 这将是你正在寻找的路径,除非有一个MyClass.send :include, Foo其他地方然后定义了MyClass ...

Note : For Ruby 1.8.6, require 'backports' or change the partition to something else. 注意 :对于Ruby 1.8.6, require 'backports'或将partition更改为其他内容。

There's no built-in way to find out where a module or class was defined (afaik). 没有内置的方法来找出模块或类的定义位置(afaik)。 In Ruby, you can re-open a module/class at any time and any place and add or change behavior. 在Ruby中,您可以随时随地重新打开模块/类,并添加或更改行为。 This means, there's usually no single place where a module/class gets defined and such a method wouldn't make sense. 这意味着,通常没有单独的地方定义模块/类,这样的方法没有意义。

In your application, you can however stick to some convention so that you are able to construct the source filename. 在您的应用程序中,您可以坚持一些约定,以便您能够构造源文件名。 Eg in Rails, a pages controller is by convention named PagesController and gets defined primarily in the file app/controllers/pages_controller.rb. 例如,在Rails中,页面控制器按照惯例命名为PagesController,主要在app / controllers / pages_controller.rb文件中定义。

Does this do what you want? 这样做你想要的吗?

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

Edit: changed according to comments. 编辑:根据评论更改。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM