Who required that!?

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
.
Finished in 0.001158 seconds.

1 tests, 2 assertions, 0 failures, 0 errors

test/unit/test_attributes.rb
Loaded suite -e
Started
..
Finished in 0.001688 seconds.

2 tests, 2 assertions, 0 failures, 0 errors

test/unit/test_autoarray.rb
"./pkg/facets-2.0.2/test/unit/test_infinity.rb"

···

-----------------------------------
["./pkg/facets-2.0.2/test/unit/test_infinity.rb:15:in `require'", "./
pkg/facets-2.0.2/test/unit/test_infinity.rb:15", "/usr/lib/ruby/1.8/
test/unit/collector/dir.rb:90:in `require'", "/usr/lib/ruby/1.8/test/
unit/collector/dir.rb:90:in `collect_file'", "/usr/lib/ruby/1.8/test/
unit/collector/dir.rb:73:in `recursive_collect'", "/usr/lib/ruby/1.8/
test/unit/collector/dir.rb:58:in `each'", "/usr/lib/ruby/1.8/test/unit/
collector/dir.rb:58:in `recursive_collect'", "/usr/lib/ruby/1.8/test/
unit/collector/dir.rb:63:in `recursive_collect'", "/usr/lib/ruby/1.8/
test/unit/collector/dir.rb:58:in `each'", "/usr/lib/ruby/1.8/test/unit/
collector/dir.rb:58:in `recursive_collect'", "/usr/lib/ruby/1.8/test/
unit/collector/dir.rb:63:in `recursive_collect'", "/usr/lib/ruby/1.8/
test/unit/collector/dir.rb:58:in `each'", "/usr/lib/ruby/1.8/test/unit/
collector/dir.rb:58:in `recursive_collect'", "/usr/lib/ruby/1.8/test/
unit/collector/dir.rb:63:in `recursive_collect'", "/usr/lib/ruby/1.8/
test/unit/collector/dir.rb:58:in `each'", "/usr/lib/ruby/1.8/test/unit/
collector/dir.rb:58:in `recursive_collect'", "/usr/lib/ruby/1.8/test/
unit/collector/dir.rb:63:in `recursive_collect'", "/usr/lib/ruby/1.8/
test/unit/collector/dir.rb:58:in `each'", "/usr/lib/ruby/1.8/test/unit/
collector/dir.rb:58:in `recursive_collect'", "/usr/lib/ruby/1.8/test/
unit/collector/dir.rb:29:in `collect'", "/usr/lib/ruby/1.8/test/unit/
autorunner.rb:68", "/usr/lib/ruby/1.8/test/unit/autorunner.rb:213:in
`[]'", "/usr/lib/ruby/1.8/test/unit/autorunner.rb:213:in `run'", "/usr/
lib/ruby/1.8/test/unit/autorunner.rb:12:in `run'", "/usr/lib/ruby/1.8/
test/unit.rb:278", "-e:3"]
-----------------------------------

test/unit/test_basicobject.rb
Loaded suite -e
Started
.......
Finished in 0.004726 seconds.

7 tests, 13 assertions, 0 failures, 0 errors

... and so on w/o issue ...

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/

···

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.

--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama

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.

···

On Nov 1, 10:38 pm, "ara.t.howard" <ara.t.how...@gmail.com> wrote:

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

}

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 :old_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

···

On 2 Nov 2007, at 11:38, ara.t.howard wrote:

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
}

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"]

Alex Gutteridge wrote:

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 :old_require :require
     define_method(:require) do |*a|
       old_require(*a)
       h[a.first] = caller
     end
   end
}

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

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

Kind regards

robert

···

2007/11/2, Trans <transfire@gmail.com>:

On Nov 1, 10:38 pm, "ara.t.howard" <ara.t.how...@gmail.com> wrote:
> 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.

--
use.inject do |as, often| as.you_can - without end

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 :old_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 :old_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

···

On 11/2/07, Alex Gutteridge <alexg@kuicr.kyoto-u.ac.jp> wrote:

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 :old_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

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.

···

On Nov 2, 5:40 am, "Robert Klemme" <shortcut...@googlemail.com> wrote:

2007/11/2, Trans <transf...@gmail.com>:

> On Nov 1, 10:38 pm, "ara.t.howard" <ara.t.how...@gmail.com> wrote:
> > 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)?

yes that's it - holding the state via closure saves namespace. sometimes it's not possible, but it seems like a good idea to try it first.

cheers.

a @ http://codeforpeople.com/

···

On Nov 2, 2007, at 12:35 AM, Joel VanderWerf wrote:

Maybe to avoid exposing the constant, H?

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

Sean O'Halpin wrote:

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?

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

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

···

On 02.11.2007 15:21, transfire@gmail.com wrote:

On Nov 2, 5:40 am, "Robert Klemme" <shortcut...@googlemail.com> wrote:

2007/11/2, Trans <transf...@gmail.com>:

On Nov 1, 10:38 pm, "ara.t.howard" <ara.t.how...@gmail.com> wrote:

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?

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 :slight_smile:

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

···

On 11/2/07, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:

Sean O'Halpin wrote:

> 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?

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

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.

···

On Nov 2, 1:30 pm, Robert Klemme <shortcut...@googlemail.com> wrote:

On 02.11.2007 15:21, transf...@gmail.com wrote:

> On Nov 2, 5:40 am, "Robert Klemme" <shortcut...@googlemail.com> wrote:
>> 2007/11/2, Trans <transf...@gmail.com>:

>>> On Nov 1, 10:38 pm, "ara.t.howard" <ara.t.how...@gmail.com> wrote:
>>>> 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.

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

···

On 11/2/07, Sean O'Halpin <sean.ohalpin@gmail.com> wrote:

On 11/2/07, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:
> Sean O'Halpin wrote:
>
> > 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?
>
> --
> vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
>
>
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 :slight_smile:

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

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

···

On 02.11.2007 19:45, transfire@gmail.com wrote:

On Nov 2, 1:30 pm, Robert Klemme <shortcut...@googlemail.com> wrote:

On 02.11.2007 15:21, transf...@gmail.com wrote:

On Nov 2, 5:40 am, "Robert Klemme" <shortcut...@googlemail.com> wrote:

2007/11/2, Trans <transf...@gmail.com>:

On Nov 1, 10:38 pm, "ara.t.howard" <ara.t.how...@gmail.com> wrote:

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.