[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

[Q]: How can I find the filename where a class is defined?

George Moschovitis

1/28/2005 11:20:00 AM

Hello everyone,

I would like to find the filename where a given class is defined.
One simple solution is the following:

class MyClass
SOURCE_FILENAME = __FILE__
....
end

then the filename is:

MyClass::SOURCE_FILENAME

This is inelegant though, is there a better solution?
Thanks in advance,
George

12 Answers

Pit Capitain

1/28/2005 1:52:00 PM

0

Hi George!

> I would like to find the filename where a given class is defined.

Since a class can be spread over multiple files, you have to define which one(s)
you want to get.

> class MyClass
> SOURCE_FILENAME = __FILE__
> ...
> end
>
> This is inelegant though, is there a better solution?

I cannot think of something simpler / better / more elegant...

Regards,
Pit


George Moschovitis

1/28/2005 2:36:00 PM

0

> Since a class can be spread over multiple files, you have to define
which
> one(s) you want to get.

My class is defined in one file only. I dont want a general solution. I
want a solution for classes defined in a single file. Any other ideas?
-g.

Michael Neumann

1/28/2005 2:49:00 PM

0

George Moschovitis wrote:
>>Since a class can be spread over multiple files, you have to define
>
> which
>
>>one(s) you want to get.
>
>
> My class is defined in one file only. I dont want a general solution. I
> want a solution for classes defined in a single file. Any other ideas?

Yes, that's what I needed last night, too (and some month ago where I
considered Wee+templating).

class Object
class << self
attr_accessor :classdef_in_file

alias __old_inherited inherited
def inherited(klass)
klass.classdef_in_file = caller.last.split(":").first
__old_inherited(klass)
end
end
end


# in file test.rb

class MyClass; end
p MyClass.classdef_in_file # => test.rb


Regards,

Michael



Alexander Kellett

1/28/2005 2:51:00 PM

0

On Jan 28, 2005, at 3:40 PM, George Moschovitis wrote:
>> Since a class can be spread over multiple files, you have to define
> which
>> one(s) you want to get.
>
> My class is defined in one file only. I dont want a general solution. I
> want a solution for classes defined in a single file. Any other ideas

t.rb
class Class
def inherited t
puts "class #{t} created at #{caller.first}"
end
end
require 'g.rb'

g.rb:
class Blah
end

->

class Blah created at ./g.rb:1



George Moschovitis

1/28/2005 2:59:00 PM

0

> Yes, that's what I needed last night, too (and some month ago where I
> ...
> class MyClass; end
> p MyClass.classdef_in_file # => test.rb

Thank you very much!

> considered Wee+templating).

I want this for a similar reason (new version of controller/action
reloading in Nitro)

-g.

--
http://www.rubyforge.com/proj...

Robert Klemme

1/28/2005 3:43:00 PM

0


"George Moschovitis" <george.moschovitis@gmail.com> schrieb im Newsbeitrag
news:1106922976.553171.111240@c13g2000cwb.googlegroups.com...
> > Since a class can be spread over multiple files, you have to define
> which
> > one(s) you want to get.
>
> My class is defined in one file only. I dont want a general solution. I
> want a solution for classes defined in a single file. Any other ideas?
> -g.

Maybe you can cook something up with set_trace_func. So you can set the
trace funtion at the beginning of your script and fill some global mapping
from class to file name.

robert

Pit Capitain

1/28/2005 4:11:00 PM

0

Michael Neumann schrieb:
>
> class Object
> class << self
> attr_accessor :classdef_in_file
>
> alias __old_inherited inherited
> def inherited(klass)
> klass.classdef_in_file = caller.last.split(":").first
> __old_inherited(klass)
> end
> end
> end

This is a nice idea!

Note that it doesn't work on Windows, though, cause there you have filenames
with colons ("C:/xxx"). You could change the line

> klass.classdef_in_file = caller.last.split(":").first

to

> klass.classdef_in_file = caller.last.sub(/:\d+$/, "")


BTW: now I can finally get rid of all those ugly

if $0 == __FILE__
end

Code :-)

Thanks for the reminder,
Pit


Sea&Gull

1/28/2005 4:43:00 PM

0

Michael Neumann wrote:
> George Moschovitis wrote:
>
>>> Since a class can be spread over multiple files, you have to define
>>
>>
>> which
>>
>>> one(s) you want to get.
>>
>>
>>
>> My class is defined in one file only. I dont want a general solution. I
>> want a solution for classes defined in a single file. Any other ideas?
>
>
> Yes, that's what I needed last night, too (and some month ago where I
> considered Wee+templating).
>
> class Object
> class << self
> attr_accessor :classdef_in_file
>
> alias __old_inherited inherited
> def inherited(klass)
> klass.classdef_in_file = caller.last.split(":").first
> __old_inherited(klass)
> end
> end
> end

Don't you forget

private :inherited

?

:-)

Also I would like to ask why you used "class Object" but not "class Class"?
There are some reasons I haven't seen?

--
s&g

Zach Dennis

1/28/2005 6:02:00 PM

0

>>>George Moschovitis wrote:

>>> My class is defined in one file only. I dont want a general solution. I
>>> want a solution for classes defined in a single file. Any other ideas?

I dont' know what kind of performance you are looking for, but if you
know the file:

classes = {}
File.open( "file.rb" ) do |file|
file.each_line do |line|
next unless line =~ /\s*class\s*(\w+)/
classes[ $1 ] = file.lineno
end
end

puts "I found the class MyClass in file file.rb at line
#{classes['MyClass']}"

This will build a hash of your class to lineno found in the source
"file.rb". the "file.rb" could also be replaced with just saying
__FILE__ if you are wanting to parse the currently loaded file.

This could easily be expanded to suit any need, but granted it reparses
your source files and thus is slower and less efficient,

Zach


Zach Dennis

1/28/2005 6:09:00 PM

0

Zach Dennis wrote:
>>>> George Moschovitis wrote:
>
>
>>>> My class is defined in one file only. I dont want a general solution. I
>>>> want a solution for classes defined in a single file. Any other ideas?
>
>
> I dont' know what kind of performance you are looking for, but if you
> know the file:
>
> classes = {}
> File.open( "file.rb" ) do |file|
> file.each_line do |line|
> next unless line =~ /\s*class\s*(\w+)/
> classes[ $1 ] = file.lineno
> end
> end
>

If you need it to gooo real fast, we can write a c extension =) and add
more functions so we don't get charged with being wasteful... The usage
could be similar to:

RubySourceParser::find_method_decl( "mymethod" )
=>[[Class1,"file.rb", lineno=1044], [Class2, "file2.rb", lineno=56]]

RubySourceParser::find_method_decl( "Class1", "mymethod" ) => ...etc...

RubySourceParser::find_class_decl( "Class1" ) => ["file1.rb",lineno=10]

RubySourceParser::find_module_decl( "...etc..." )

Perhaps this is overkill, but I am on a ruby high right now, after I
wrote a mini-library to handle NetworkDrives in Windows. It is a small
very simple thing, but it makes me sooo happy. Happying Rubying!

Zach