"cyclic include" error inside anonymous module

(Brian Candler) #1

Guy, I'm afraid you're being a little terse for a dimwit like me :slight_smile:

> load 'ruby4.rb', true

ruby create an anonymous module (wrapper) to make the load and protect
(i.e. clone) main (ruby_top_self)

OK, I think I get this. Changing the code to

$ cat ruby3.rb
p self, self.class, self.object_id
load 'ruby4.rb', true
$ cat ruby4.rb
p self, self.class, self.object_id
module M
end
include M
$ ruby ruby3.rb
main
Object
67382492
main
Object
67351832
./ruby4.rb:4:in `append_features': cyclic include detected (ArgumentError)

So, 'main' is a different object when in ruby4.rb. I don't know how to
demonstrate that the module scope is different inside the second file, but I
believe it. If I understand rightly, it just means that a constant
definition like

    ABC=1

will be defined as

    <anonymous>::ABC=1

rather than going into the top-level namespace. Is that correct?

> module M

each time a module is created, ruby include/extend the wrapper in it.

I don't understand that response (although I'm aware that English isn't your
first language). When you say 'wrapper' are you talking about the anonymous
module, or the new 'main' object? (I don't think they can be the same thing,
since main is an Object, not a Module)

I think you must mean the anonymous module.

So, writing 'module M' is defining a module <anonymous>::M here.

If that's right, what I don't get is when you say "ruby include/extend the
wrapper _in it_". Are you saying that Ruby does

     main.include <anonymous>::M

automatically? Or is it doing

     <anonymous>.include M

Or something else? If so, why? Is this some special behaviour triggered only
when load(file,true) is in force?

> end

> include M

when you make the include, it detect the wrapper (it's in module).
Consequence :

Probably because I don't understand the earlier part, I don't understand the
consequence. If I write:

    module M
    end
    include M
    include M

and run it (without a wrapper) then it works fine. That is, the fact that
module M had already been included in 'main' does not cause the 'cyclic'
error.

I've tried replicating various scenarios to try and understand what you're
trying to say:

    module Anonymous
    module M
    end
    Anonymous.include M
    include M
    end

Gives:
ruby6.rb:4: private method `include' called for Anonymous:Module (NoMethodError)

    module Anonymous
    module M
    end
    Anonymous.instance_eval { include M }
    include M
    end

Gives no error.

    module Anonymous
    module M
    end
    Anonymous.extend M
    include M
    end

Gives no error either.

What I'd like is to be able to replicate the 'cyclic' error without using
load(filename,true) - then I might understand what's going on!

Regards,

Brian.

(ts) #2

I don't understand that response (although I'm aware that English isn't your
first language).

Like I've said previously, I prefer ruby and C :slight_smile:

moulon% cat b.rb
#!/usr/bin/ruby
module Anonymous
   module M
      include Anonymous
      extend Anonymous
   end

   include M
end

moulon%

moulon% ./b.rb
./b.rb:8:in `append_features': cyclic include detected (ArgumentError)
  from ./b.rb:8
moulon%

Guy Decoux