1

I'd like to access the source of a class like so:

# Module inside file1.rb
module MetaFoo
  class << Object
    def bar
      # here I'd like to access the source location of the Foo class definition
      # which should result in /path/to/file2.rb
    end
  end
end

# Class inside another file2.rb
class Foo
  bar
end

I could do something bad like:

self.send(:caller)

and try to parse the output, or even:

class Foo
  bar __FILE__
end

But that's not, want I want, I had the hope there is a more elegant solution for that.

Any hints are welcome.

GeorgieF
  • 2,687
  • 5
  • 29
  • 43
  • You can access the location of the source of a method, but asking for the location for a class is too vague. – sawa Sep 12 '12 at 18:12

2 Answers2

2

Both $0 and __FILE__ will be useful to you.

$0 is the path of the running application.

__FILE__ is the path of the current script.

So, __FILE__ will be the script or module, even if it's been required.

Also, __LINE__ might be useful to you.

See "What does __FILE__ mean in Ruby?", "What does if __FILE__ == $0 mean in Ruby" and "What does class_eval <<-“end_eval”, __FILE__, __LINE__ mean in Ruby? for more information.

Community
  • 1
  • 1
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • Tin Man, thank you for your input. The problem in fact is, that the definition of bar resides inside a module, and the class Foo is located in a different file. So when method bar is called from within Foo, self is Foo, but __FILE__ is the location of the module which has the bar method definition inside. __LINE__ behaves the same way, and $0 does not seem to provide the info I need at that time. Anyway, thank you for yout help. – GeorgieF Sep 12 '12 at 19:46
1

You could try calling:

caller.first

That will print off the file name and line number. Using your demonstration files above (with slight modifications:

file1.rb:

module MetaFoo
  class << Object
    def bar
      puts caller.first # <== the magic...
    end
  end
end

file2.rb:

require './file1.rb'

class Foo
  bar
end

When I run ruby file2.rb, I get the following output:

nat$ ruby file2.rb 
file2.rb:4:in `<class:Foo>'

That's what you want, right?

Nat Ritmeyer
  • 5,634
  • 8
  • 45
  • 58