开发者

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?
  开发者_如何学Go  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:

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

Note: For Ruby 1.8.6, require 'backports' or change the partition to something else.


There's no built-in way to find out where a module or class was defined (afaik). In Ruby, you can re-open a module/class at any time and any place and add or change behavior. 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. E.g. in Rails, a pages controller is by convention named PagesController and gets defined primarily in the file app/controllers/pages_controller.rb.


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜