Hi,
I was trying to identify the classes in a give file at the run time. the following is the code i used.
sc, ec = [], []
ObjectSpace.each_object(Class) { |c| sc << c }
require 'Roman.rb'
ObjectSpace.each_object(Class) { |c| ec << c }
new_classes = ec - sc
puts new_classes
sc, ec = [], []
ObjectSpace.each_object(Class) { |c| sc << c }
require 'Roman1.rb'
ObjectSpace.each_object(Class) { |c| ec << c }
new_classes = ec - sc
puts new_classes
Both roman.rb and roman1.rb has the same class Roman.
the first time i print the new_classes i can see the Roman class in the output but the second one does not print because the class Roman is arleady read previously.
is there a way i can over come this problem and identify the Roman class twice.
Thanks,
Navya.
···
---------------------------------
New Yahoo! Messenger with Voice. Call regular phones from your PC and save big.
Navya Amerineni wrote:
Hi,
I was trying to identify the classes in a give file at the run time. the following is the code i used.
sc, ec = ,
ObjectSpace.each_object(Class) { |c| sc << c }
require 'Roman.rb'
ObjectSpace.each_object(Class) { |c| ec << c }
new_classes = ec - sc
puts new_classes
sc, ec = ,
ObjectSpace.each_object(Class) { |c| sc << c }
require 'Roman1.rb'
ObjectSpace.each_object(Class) { |c| ec << c }
new_classes = ec - sc
puts new_classes
Both roman.rb and roman1.rb has the same class Roman.
the first time i print the new_classes i can see the Roman class in the output but the second one does not print because the class Roman is arleady read previously.
is there a way i can over come this problem and identify the Roman class twice.
One way is to wrap the file in a module, so that the constants defined
in it will not collide with other constants.
file = "some/file"
m = Module.new
m.module_eval(IO.read(file), File.expand_path(file))
p m.constants
But then the Roman module won't be available except as m::Roman. To fix
this, you could include m into any class or module that needs to use Roman.
···
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
Navya Amerineni wrote:
Hi,
I was trying to identify the classes in a give file at the run time. the following is the code i used.
sc, ec = ,
ObjectSpace.each_object(Class) { |c| sc << c }
require 'Roman.rb'
ObjectSpace.each_object(Class) { |c| ec << c }
new_classes = ec - sc
puts new_classes
sc, ec = ,
ObjectSpace.each_object(Class) { |c| sc << c }
require 'Roman1.rb'
ObjectSpace.each_object(Class) { |c| ec << c }
new_classes = ec - sc
puts new_classes
Both roman.rb and roman1.rb has the same class Roman.
the first time i print the new_classes i can see the Roman class in the output but the second one does not print because the class Roman is arleady read previously.
is there a way i can over come this problem and identify the Roman class twice.
Way #1, store the new classes in a hash. This way you won't be overriding any classes you've previously loaded.
Way #2, use one array to store new classes, and then each time you compute the "new_classes" after you load a file, merge those
into your one authoriatize array. This way you won't be overriding any classes you've previously loaded.
Way #3, pass a string into a new ruby process which loads the files and outputs the new classes. Read these in and then use Way #1
or Way #2 to store the classes. This is a bit hackish, but it works and it leaves your toplevel ruby process namespace alone.
Here is the idea of Way #3
str =<<-'EOT'
def count_classes( arg )
arr =
ObjectSpace.each_object( arg ){ |c| arr << c }
arr
end
orig_classes = count_classes( Class )
require "load"
new_classes = count_classes( Class ) - orig_classes
puts new_classes.join( "\n" )
EOT
child = IO.popen( "ruby -e '#{str}'", "r" )
new_classes = child.readlines.map!{ |s| s.chomp! }
puts new_classes
Zach
dblack@wobblini.net wrote:
...
Also I think that if the read-in file uses the ::Const construct,
those classes won't get counted.
You mean like this:
$ cat t.rb
class ::Foo
end
$ ruby -e 'load "t.rb"; p Foo'
Foo
$ ruby -e 'load "t.rb"; ObjectSpace.each_object(Class) {|c| p c if
c.name == "Foo"}'
Foo
So it doesn't look like that works, unless I'm misunderstanding...
···
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
dblack@wobblini.net wrote:
Hi --
...
Also I think that if the read-in file uses the ::Const construct,
those classes won't get counted.
You mean like this:
$ cat t.rb
class ::Foo
end
$ ruby -e 'load "t.rb"; p Foo'
Foo
$ ruby -e 'load "t.rb"; ObjectSpace.each_object(Class) {|c| p c if
c.name == "Foo"}'
Foo
So it doesn't look like that works, unless I'm misunderstanding...
Yes, that's what I meant; if you have ::Foo in your file, then you
won't get a Foo class in the module you wrap in, so you won't get the
right count of modules in the file.
Oh, I see--I thought you meant it was a workaround, but it's actually a
limitation of the module wrapping trick. Good point.
···
On Tue, 11 Apr 2006, Joel VanderWerf wrote:
dblack@wobblini.net wrote:
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407