# Re: Reflection and files

**URL:** <https://www.ruby-forum.com/t/re-reflection-and-files/68356>\
**Category:** Ruby\
**Created:** [September 12, 2006, 1:07am UTC](https://www.ruby-forum.com/t/re-reflection-and-files/68356 "2006-09-12T01:07:24Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [September 12, 2006, 1:07am UTC](https://www.ruby-forum.com/t/re-reflection-and-files/68356/1 "2006-09-12T01:07:24Z")

</div>

> Suppose I have a ruby file with a single class. Is it  
> possible to write a  
> ruby script that can extract the class name from the file?  
> […]  
> Is it possible to extract the class name via reflection?

Well, here’s one terrible idea. (It’s ‘terrible’ because it’s brittle,  
and only works if no other files defining new classes have been defined,  
and will break if a new Ruby release defines a new class.)

BUILTIN\_CLASSES = %w| ArgumentError Array Bignum Binding Class  
Continuation  
Data Date DateTime Dir EOFError Exception FalseClass File Fixnum Float  
FloatDomainError Hash IO IOError IndexError Integer Interrupt LoadError  
LocalJumpError MatchData MatchData Method Module NameError NilClass  
NoMemoryError NoMethodError NotImplementedError Numeric Object Proc  
Range  
RangeError Rational Regexp RegexpError RuntimeError ScriptError  
SecurityError SignalException StandardError String Struct Symbol  
SyntaxError SystemCallError SystemExit SystemStackError Thread  
ThreadError ThreadGroup Time TrueClass TypeError UnboundMethod  
ZeroDivisionError |.map{ |n| Object.const\_get( n ) }

class Foo; end

nonstandard\_classes = Object.constants.map{ |name|  
klass = Object.const\_get( name )  
Class === klass ? klass : nil  
}.compact - BUILTIN\_CLASSES

puts nonstandard\_classes  
#=\> Foo

---

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [September 12, 2006, 4:11am UTC](https://www.ruby-forum.com/t/re-reflection-and-files/68356/2 "2006-09-12T04:11:38Z")

</div>

Wouldn’t be easier to give the file the same name of the class?  
Like some\_class.rb to the file and SomeClass to the class?

I don’t know what you’re trying, so just a thought.

Cheers

---

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [September 12, 2006, 10:36am UTC](https://www.ruby-forum.com/t/re-reflection-and-files/68356/3 "2006-09-12T10:36:25Z")

</div>

Gavin K. wrote:

> Well, here’s one terrible idea. (It’s ‘terrible’ because it’s brittle,  
> and only works if no other files defining new classes have been defined,  
> and will break if a new Ruby release defines a new class.)

How about:

def get\_class\_from\_file(file)  
consts = Object.constants  
require file  
return (Object.constants - consts)[0]  
end

p get\_class\_from\_file(’/path/to/some\_file.rb’)

Regards,  
Jordan

---

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [September 12, 2006, 7:59pm UTC](https://www.ruby-forum.com/t/re-reflection-and-files/68356/4 "2006-09-12T19:59:36Z")

</div>

MonkeeSage wrote:

> return (Object.constants - consts)[0]  
> end
> 
> p get\_class\_from\_file(’/path/to/some\_file.rb’)

Doesn’t work if file requires some other file (such as a ruby std lib  
file). Also, not thread safe. Also, the class may be defined as

class Foo::Bar  
end

and it will not show up in Object.constants.

Also, there might be other constants:

K=1  
class Foo; end

It’s a hard problem in ruby…

---

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [September 14, 2006, 12:44pm UTC](https://www.ruby-forum.com/t/re-reflection-and-files/68356/5 "2006-09-14T12:44:36Z")

</div>

MonkeeSage wrote:

> How about:
> 
> def get\_class\_from\_file(file)  
> consts = Object.constants  
> require file  
> return (Object.constants - consts)[0]  
> end

Also doesn’t work if the file was already required before.

David V.

---

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [September 12, 2006, 8:11pm UTC](https://www.ruby-forum.com/t/re-reflection-and-files/68356/6 "2006-09-12T20:11:38Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

Gavin K. wrote:

> > Suppose I have a ruby file with a single class. Is it  
> > possible to write a  
> > ruby script that can extract the class name from the file?  
> > […]  
> > Is it possible to extract the class name via reflection?
> 
> Well, here’s one terrible idea. (It’s ‘terrible’ because it’s brittle,  
> and only works if no other files defining new classes have been defined,  
> and will break if a new Ruby release defines a new class.)

I agree.

I just wanted to share what I had in mind, which will not break because  
of a new ruby version (I guess):

old\_classes = self.class.constants.find\_all {|x|  
self.class.const\_get(x).class == Class }.compact

require’my\_lib’

all\_classes = self.class.constants.find\_all {|x|  
self.class.const\_get(x).class == Class }.compact

new\_classes = (all\_classes - old\_classes).collect {|x|  
self.class.const\_get(x) }

Stefan  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.2.2 (GNU/Linux)  
Comment: Using GnuPG with Mozilla - [http://enigmail.mozdev.org](http://enigmail.mozdev.org)

iD8DBQFFBveV9S2Eui6zfdQRAlAOAKCjHM1eUg3ueMnoQ7krW2D5RBBmxgCdHyTs  
olOXERUvErsSh6GxLhC8s34=  
=UYzZ  
-----END PGP SIGNATURE-----
