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.
精彩评论