Who required that!?

T

transfire

Is there any way to ask a file what other file require/load 'd it? I
imagine this has been asked before but I couldnt seem to find good
terms to search for it.

The reason I ask is b/c I am getting the freakiest error. I'm running
my test, right. Now when I run them one at a time by hand they all
work fine. But if I run them via a script that in turn runs them one
at time for me, eg:

test_files.each do |file|
sh %{ruby -e 'puts "\n\n#{file}"; load "#{file}"' >> #{output}}
end

Then I get a very very very strange error where, test_autoarray.rb
seems to somehow cause text_infinity.rb to load even though they have
no connection whatsoever, but worse, it's not the test_infinity.rb
that is supposed to load about 70 test files later, but rather the
test file in my pkg/ staging folder! I have no idea how it picks that
up. The one thing that strikes me is that the pkg/ file it hard linked
to the real file, but I don't see how Ruby could possibly know that.

Below is a snip of the output. I added a 'p __FILE__' and a 'p caller'
to the top of test_infinity.rb to show the file it's coming from. As
you can see it's running right along fine but when it hits
test_autoarray.rb that's when it goes wack. But then it goes right
back to normal and finishes without issue.

T.

...

test/unit/hash/test_at.rb
Loaded suite -e
Started
 
A

ara.t.howard

Is there any way to ask a file what other file require/load 'd it? I
imagine this has been asked before but I couldnt seem to find good
terms to search for it.

cfp:~ > cat a.rb
p Kernel.requiree('main')

require 'b'

p Kernel.requiree('main')




BEGIN {
module Kernel
h = Hash.new
define_method:)requiree) do |of|
h[of]
end

r = method :require
define_method:)require) do |*a|
r.call *a
h[a.first] = caller
end
end
}


cfp:~ > cat b.rb
require 'main'


cfp:~ > ruby a.rb
nil
["./b.rb:1", "a.rb:20:in `require'", "a.rb:20:in `call'", "a.rb:20:in
`require'", "a.rb:4"]




a @ http://codeforpeople.com/
 
T

transfire

Is there any way to ask a file what other file require/load 'd it? I
imagine this has been asked before but I couldnt seem to find good
terms to search for it.

cfp:~ > cat a.rb
p Kernel.requiree('main')

require 'b'

p Kernel.requiree('main')

BEGIN {
module Kernel
h = Hash.new
define_method:)requiree) do |of|
h[of]
end

r = method :require
define_method:)require) do |*a|
r.call *a
h[a.first] = caller
end
end

}

Doh! Of course!

Thanks Ara, that allowed me to figure it out.

Turns out using 'load' to load the test rather then passing it
straight to the ruby command, for some reason, gives test/unit the
idea that it should go out and hunt for every file it can find with a
test in it, including the copies in pkg/. That seems nuts me, but now
I recall having to specify some parameter to reign test/unit in before
--don't recall off hand what it was though. I'll have to track that
down. In any case

test_files.each do |file|
sh %{ruby -e #{file} >> #{output}}
end

works, and that's good enough.

Thanks!
T.
 
A

alexg

Is there any way to ask a file what other file require/load 'd it? I
imagine this has been asked before but I couldnt seem to find good
terms to search for it.

cfp:~ > cat a.rb
p Kernel.requiree('main')

require 'b'

p Kernel.requiree('main')

BEGIN {
module Kernel
h = Hash.new
define_method:)requiree) do |of|
h[of]
end

r = method :require
define_method:)require) do |*a|
r.call *a
h[a.first] = caller
end
end
}


cfp:~ > cat b.rb
require 'main'


cfp:~ > ruby a.rb
nil
["./b.rb:1", "a.rb:20:in `require'", "a.rb:20:in `call'", "a.rb:
20:in `require'", "a.rb:4"]


Ara, out of curiosity, is there any reason why you don't write the
Kernel modification code as:

module Kernel
H = {}
def requiree(of)
H[of]
end

alias :eek:ld_require :require
def require(*a)
old_require(*a)
H[a.first] = caller
end
end

Is there any difference between the two versions, or is it just a
style preference?

Alex Gutteridge

Bioinformatics Center
Kyoto University
 
V

vjoel

Alex said:
Is there any difference between the two versions, or is it just a style
preference?

Maybe to avoid exposing the constant, H?

But unfortunately it breaks gems... Maybe because it references
Kernel#require before gem does its thing with it? Not sure why the same
doesn't happen with alias, though.

Anyway, combining your approach with Ara's seems to take the best of each:


p Kernel.requiree('main')

require 'b'

p Kernel.requiree('main')

require 'fox16' # or your favorite gem

BEGIN {
module Kernel
h = Hash.new
define_method:)requiree) do |of|
h[of]
end

alias :eek:ld_require :require
define_method:)require) do |*a|
old_require(*a)
h[a.first] = caller
end
end
}
 
S

shortcutter

2007/11/2 said:
Is there any way to ask a file what other file require/load 'd it? I
imagine this has been asked before but I couldnt seem to find good
terms to search for it.

cfp:~ > cat a.rb
p Kernel.requiree('main')

require 'b'

p Kernel.requiree('main')

BEGIN {
module Kernel
h = Hash.new
define_method:)requiree) do |of|
h[of]
end

r = method :require
define_method:)require) do |*a|
r.call *a
h[a.first] = caller
end
end

}

Doh! Of course!

Thanks Ara, that allowed me to figure it out.

Turns out using 'load' to load the test rather then passing it
straight to the ruby command, for some reason, gives test/unit the
idea that it should go out and hunt for every file it can find with a
test in it, including the copies in pkg/. That seems nuts me, but now
I recall having to specify some parameter to reign test/unit in before
--don't recall off hand what it was though. I'll have to track that
down. In any case

test_files.each do |file|
sh %{ruby -e #{file} >> #{output}}
end

works, and that's good enough.

Just out of curiosity: why don't you use the test packages mechanisms
to run multiple tests (TestSuite)?

Kind regards

robert
 
T

transfire

2007/11/2, Trans <[email protected]>:




On Nov 1, 2007, at 6:18 PM, Trans wrote:
Is there any way to ask a file what other file require/load 'd it? I
imagine this has been asked before but I couldnt seem to find good
terms to search for it.
cfp:~ > cat a.rb
p Kernel.requiree('main')
require 'b'
p Kernel.requiree('main')
BEGIN {
module Kernel
h = Hash.new
define_method:)requiree) do |of|
h[of]
end
r = method :require
define_method:)require) do |*a|
r.call *a
h[a.first] = caller
end
end
}
Doh! Of course!
Thanks Ara, that allowed me to figure it out.
Turns out using 'load' to load the test rather then passing it
straight to the ruby command, for some reason, gives test/unit the
idea that it should go out and hunt for every file it can find with a
test in it, including the copies in pkg/. That seems nuts me, but now
I recall having to specify some parameter to reign test/unit in before
--don't recall off hand what it was though. I'll have to track that
down. In any case
test_files.each do |file|
sh %{ruby -e #{file} >> #{output}}
end
works, and that's good enough.

Just out of curiosity: why don't you use the test packages mechanisms
to run multiple tests (TestSuite)?

I need to keep them isolated to make sure they all work on their own.
How would you use the test/unit mechanisms to do that?

Thanks,
T.
 
R

Robert Klemme

2007/11/2, Trans <[email protected]>:




On Nov 1, 2007, at 6:18 PM, Trans wrote:
Is there any way to ask a file what other file require/load 'd it? I
imagine this has been asked before but I couldnt seem to find good
terms to search for it.
cfp:~ > cat a.rb
p Kernel.requiree('main')
require 'b'
p Kernel.requiree('main')
BEGIN {
module Kernel
h = Hash.new
define_method:)requiree) do |of|
h[of]
end
r = method :require
define_method:)require) do |*a|
r.call *a
h[a.first] = caller
end
end
}
Doh! Of course!
Thanks Ara, that allowed me to figure it out.
Turns out using 'load' to load the test rather then passing it
straight to the ruby command, for some reason, gives test/unit the
idea that it should go out and hunt for every file it can find with a
test in it, including the copies in pkg/. That seems nuts me, but now
I recall having to specify some parameter to reign test/unit in before
--don't recall off hand what it was though. I'll have to track that
down. In any case
test_files.each do |file|
sh %{ruby -e #{file} >> #{output}}
end
works, and that's good enough.
Just out of curiosity: why don't you use the test packages mechanisms
to run multiple tests (TestSuite)?

I need to keep them isolated to make sure they all work on their own.
How would you use the test/unit mechanisms to do that?

I am not sure what you mean by "on their own". Do you expect side
effects from test executions? From what I understand a TestCase should
ideally be independent and probably also side effect free. Then you
could easily lump them into a single TestSuite. The only issue I can
think of off the top of my head would be class instance variables and
required files which might yield different results - but then again,
relying on a specific require order is probably not a good idea in its own.

Kind regards

robert
 
T

transfire

2007/11/2, Trans <[email protected]>:
On Nov 1, 2007, at 6:18 PM, Trans wrote:
Is there any way to ask a file what other file require/load 'd it? I
imagine this has been asked before but I couldnt seem to find good
terms to search for it.
cfp:~ > cat a.rb
p Kernel.requiree('main')
require 'b'
p Kernel.requiree('main')
BEGIN {
module Kernel
h = Hash.new
define_method:)requiree) do |of|
h[of]
end
r = method :require
define_method:)require) do |*a|
r.call *a
h[a.first] = caller
end
end
}
Doh! Of course!
Thanks Ara, that allowed me to figure it out.
Turns out using 'load' to load the test rather then passing it
straight to the ruby command, for some reason, gives test/unit the
idea that it should go out and hunt for every file it can find with a
test in it, including the copies in pkg/. That seems nuts me, but now
I recall having to specify some parameter to reign test/unit in before
--don't recall off hand what it was though. I'll have to track that
down. In any case
test_files.each do |file|
sh %{ruby -e #{file} >> #{output}}
end
works, and that's good enough.
Just out of curiosity: why don't you use the test packages mechanisms
to run multiple tests (TestSuite)?
I need to keep them isolated to make sure they all work on their own.
How would you use the test/unit mechanisms to do that?

I am not sure what you mean by "on their own". Do you expect side
effects from test executions? From what I understand a TestCase should
ideally be independent and probably also side effect free. Then you
could easily lump them into a single TestSuite. The only issue I can
think of off the top of my head would be class instance variables and
required files which might yield different results - but then again,
relying on a specific require order is probably not a good idea in its own.

There are a couple of aspects to isolating the tests. The main one is
just making sure that a lib requires all the libs it needs to operate.
Sometimes one lib gets loaded that requires something that another
will use, so if they are both loaded you can't tell if they can act
independently. Also, it is possible that some libs are meant as
options, ie you use one or the other, but not both. I imagine there
may well be other reasons. To be thorough, I run tests in isolation,
in pairs, and as a whole. Really this has more to do with the nature
of Facets. Facets isn't just a single library, it's a (lightly
integrated) collection of them.

T.
 
R

Robert Klemme

2007/11/2, Trans <[email protected]>:
On Nov 1, 2007, at 6:18 PM, Trans wrote:
Is there any way to ask a file what other file require/load 'd it? I
imagine this has been asked before but I couldnt seem to find good
terms to search for it.
cfp:~ > cat a.rb
p Kernel.requiree('main')
require 'b'
p Kernel.requiree('main')
BEGIN {
module Kernel
h = Hash.new
define_method:)requiree) do |of|
h[of]
end
r = method :require
define_method:)require) do |*a|
r.call *a
h[a.first] = caller
end
end
}
Doh! Of course!
Thanks Ara, that allowed me to figure it out.
Turns out using 'load' to load the test rather then passing it
straight to the ruby command, for some reason, gives test/unit the
idea that it should go out and hunt for every file it can find with a
test in it, including the copies in pkg/. That seems nuts me, but now
I recall having to specify some parameter to reign test/unit in before
--don't recall off hand what it was though. I'll have to track that
down. In any case
test_files.each do |file|
sh %{ruby -e #{file} >> #{output}}
end
works, and that's good enough.
Just out of curiosity: why don't you use the test packages mechanisms
to run multiple tests (TestSuite)?
I need to keep them isolated to make sure they all work on their own.
How would you use the test/unit mechanisms to do that?
I am not sure what you mean by "on their own". Do you expect side
effects from test executions? From what I understand a TestCase should
ideally be independent and probably also side effect free. Then you
could easily lump them into a single TestSuite. The only issue I can
think of off the top of my head would be class instance variables and
required files which might yield different results - but then again,
relying on a specific require order is probably not a good idea in its own.

There are a couple of aspects to isolating the tests. The main one is
just making sure that a lib requires all the libs it needs to operate.
Sometimes one lib gets loaded that requires something that another
will use, so if they are both loaded you can't tell if they can act
independently. Also, it is possible that some libs are meant as
options, ie you use one or the other, but not both. I imagine there
may well be other reasons. To be thorough, I run tests in isolation,
in pairs, and as a whole. Really this has more to do with the nature
of Facets. Facets isn't just a single library, it's a (lightly
integrated) collection of them.

Makes perfectly sense to me. Thanks for the explanation. This would
make it interesting to have something like transactions built into the
interpreter - that way you could undefine stuff without having to
execute a new interpreter. I should go to bed now before I come up with
more silly ideas.

Kind regards

robert
 
S

sean.ohalpin

Ara, out of curiosity, is there any reason why you don't write the
Kernel modification code as:

module Kernel
H = {}
def requiree(of)
H[of]
end

alias :eek:ld_require :require
def require(*a)
old_require(*a)
H[a.first] = caller
end
end

Is there any difference between the two versions, or is it just a
style preference?

Alex Gutteridge

Bioinformatics Center
Kyoto University

It's a preference for code that will work even if someone else wants
to intercept require.

Try this:

module Kernel
H = {}
def requiree(of)
H[of]
end

alias :eek:ld_require :require
def require(*a)
old_require(*a)
H[a.first] = caller
end
end

# in another file someone has the same idea...
module Kernel
alias :eek:ld_require :require
def require(*a)
old_require(*a)
puts "I want to intercept require too"
end
end

require 'date'

puts "Here"
__END__
$ ruby alias-require.rb
alias-require.rb:9:in `old_require': stack level too deep (SystemStackError)
from alias-require.rb:9:in `old_require'
from alias-require.rb:18:in `require'
from alias-require.rb:23

Using alias is just a little too fragile. You could always generate a
unique alias name (using GUID or something) which would avoid the
problem, but grabbing a reference to the existing method and using
that is sure to work.

Regards,
Sean
 
V

vjoel

Sean said:
Using alias is just a little too fragile. You could always generate a
unique alias name (using GUID or something) which would avoid the
problem, but grabbing a reference to the existing method and using
that is sure to work.

Can you do the latter without breaking gem's require?
 
S

sean.ohalpin

Can you do the latter without breaking gem's require?
Yes, that's the point. If you redefine require by chaining to the
previous definition (rather than aliasing) no other part of the system
will know the difference. But the proof is in the pudding :)


require 'rubygems'

BEGIN {
module Kernel
h = Hash.new
define_method:)requiree) do |of|
h[of]
end

r = method :require
define_method:)require) do |*a|
r.call *a
h[a.first] = caller
end
end
}

require 'main'

p Kernel.requiree("main")

Main {
def run
puts "Made it!"
end
}

__END__
$ ruby requiree.rb
["/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:32:in
`gem_original_require'",
"/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:32:in
`require'", "requiree.rb:19"]
Made it!

Regards,
Sean
 
S

sean.ohalpin

Can you do the latter without breaking gem's require?
Yes, that's the point. If you redefine require by chaining to the
previous definition (rather than aliasing) no other part of the system
will know the difference. But the proof is in the pudding :)


require 'rubygems'

BEGIN {
module Kernel
h = Hash.new
define_method:)requiree) do |of|
h[of]
end

r = method :require
define_method:)require) do |*a|
r.call *a
h[a.first] = caller
end
end
}

require 'main'

p Kernel.requiree("main")

Main {
def run
puts "Made it!"
end
}

__END__
$ ruby requiree.rb
["/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:32:in
`gem_original_require'",
"/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:32:in
`require'", "requiree.rb:19"]
Made it!

Regards,
Sean
Scrub that - Joel you're right - it depends on load order. If you use
ruby -rubygems ... this won't work because requiree is grabbing a
reference to the original require method and so bypassing the rubygems
redefinition. It works ok if rubygems aliases requiree's require but
not the other way round. Hmmm...

Regards,
Sean
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,265
Latest member
TodLarocca

Latest Threads

Top