How can I prevent include one module multi-times?

I am looking for a method to check whether this module has been
included. Does Ruby have this feature?

From: Zhao Yi [mailto:[email protected]]

I am looking for a method to check whether this module has been

included. Does Ruby have this feature?

you can query the class/module thru #included_modules

eg,

class C
end
=> nil

C.included_modules
=> [Kernel]

module M
end
=> nil

class C
include M
end
=> C

C.included_modules
=> [M, Kernel]

or if you want to query the whole program space, search the ObjectSpace

eg,

ObjectSpace.each_object(Module).select{|m| m.class.name == “Module”}

=> [IRB, Exception2MessageMapper, Marshal, ObjectSpace, GC, Math,
Process::Sys, Process::GID, Process::UID, Process, Signal,
File::Constants, FileTest, Errno, Precision, Enumerable, Comparable,
Kernel, Readline, RubyToken, IRB::Notifier, M, IRB::MethodExtender,
IRB::ContextExtender, IRB::ExtendCommandBundle]

kind regards -botp

Zhao Yi wrote:

I am looking for a method to check whether this module has been
included. Does Ruby have this feature?

Might try parsing Object.constants for the module name.

Zhao Yi wrote:

I am looking for a method to check whether this module has been
included. Does Ruby have this feature?

What’s your question? In the subject you ask ‘How can I prevent include
one module multi-times?’ and this is checked automatically without any
special handling.

2008/9/3 Thomas B. [email protected]

Zhao Yi wrote:

I am looking for a method to check whether this module has been
included. Does Ruby have this feature?

What’s your question? In the subject you ask ‘How can I prevent include
one module multi-times?’ and this is checked automatically without any
special handling.

That’s partially correct, but you’ll find that the module’s included()
hook
gets called repeatedly:

module M
def self.included(base)
puts “included M”
end
end

class C

prints “included M” 3 times

include M
include M
include M
end

To check whether M is already mixed into C, the expression ‘M > C’
returns
true if C includes M. You could put this check inside M.included and
throw
an exception if it’s true.

Roger P. wrote:

Zhao Yi wrote:

I am looking for a method to check whether this module has been
included. Does Ruby have this feature?

Might try parsing Object.constants for the module name.

Why? That only tells you whether that module exists (and it only tells
you
that when the module is in the top-level namespace). It doesn’t tell you
whether that module has been included into anything.

2008/9/3 James C. [email protected]

special handling.
end
an exception if it’s true.

I should have mentioned that including a module multiple times will not
have
any nasty side effects on the inheritance tree of the including class –
this is checked for you.

Ah, I think I misunderstood the question. I wrote this a while ago to
find
all the descendants of a module:

ah–if the problem is determining if a descendant exists, you could
write an included(instance) method within the included Module to track.
Cheers.
-=R

2008/9/3 Sebastian H. [email protected]

Roger P. wrote:

Zhao Yi wrote:

I am looking for a method to check whether this module has been
included. Does Ruby have this feature?

Might try parsing Object.constants for the module name.

Why? That only tells you whether that module exists (and it only tells you
that when the module is in the top-level namespace). It doesn’t tell you
whether that module has been included into anything.

Ah, I think I misunderstood the question. I wrote this a while ago to
find
all the descendants of a module:

class Module
def descendants
classes = []
ObjectSpace.each_object do |klass|
next unless Module === klass
classes << klass if self > klass
end
classes
end
end

So, a module has been included if

mod.descendants.size.nonzero?