I want to get a list of modules which are included directly in the class
in ruby. Example: Suppose below are two modules and a class defined in
ruby script.
···
-------------------
module M1
…
end
module M2
…
end
class MyClass
include M1
include M2
…
end
-------------------
How can I get list of modules which are included directly in the class?
Here in above example, M1 and M2 are only included in class MyClass so I
only want a list which contains modules M1 and M2 for MyClass. If we
call “MyClass.ancestors” which returns all the modules which are include
directly or indirectly in this class and all parent class hierarchy that
exactly I don’t want to get.
Maybe my friend irb can help
irb(main):001:0> module M1; end
=> nil
irb(main):002:0> class C1; include M1 end
=> C1
irb(main):003:0> module M2; end
=> nil
irb(main):004:0> class C2 < C1; include M2 end
=> C2
irb(main):017:0> class Module
irb(main):018:1> def included_modules
irb(main):019:2> ancestors.select{|x|x.class==Module}
irb(main):020:2> end
irb(main):021:1> end
irb(main):022:0> C1.included_modules
=> [M1, Kernel]
irb(main):023:0> C2.included_modules
=> [M2, M1, Kernel]
You can get of Kernel of course if you do not want it to show up at the party.
HTH
Robert
···
On 7/25/07, Chirag Mistry <chirag80bece@gmail.com> wrote:
Hi
I want to get a list of modules which are included directly in the class
in ruby. Example: Suppose below are two modules and a class defined in
ruby script.
-------------------
module M1
…
end
module M2
…
end
class MyClass
include M1
include M2
…
end
-------------------
How can I get list of modules which are included directly in the class?
Here in above example, M1 and M2 are only included in class MyClass so I
only want a list which contains modules M1 and M2 for MyClass. If we
call "MyClass.ancestors" which returns all the modules which are include
directly or indirectly in this class and all parent class hierarchy that
exactly I don't want to get.
On Behalf Of Chirag Mistry:
# only want a list which contains modules M1 and M2 for MyClass. If we
# call “MyClass.ancestors” which returns all the modules which
# are include directly or indirectly in this class and all parent class
not stupid at all, you just overlooked a little detail, parent classes.
module M1; end
module M2; end
class C1; include M1 end
class C2 < C1; include M2 end
p C2.ancestors - (Class.new.ancestors + [C2])
Robert
···
On 7/25/07, Peña, Botp <botp@delmonte-phil.com> wrote:
On Behalf Of Chirag Mistry:
# only want a list which contains modules M1 and M2 for MyClass. If we
# call "MyClass.ancestors" which returns all the modules which
# are include directly or indirectly in this class and all parent class
I don't think that it answers the question. Look at the following
example:
irb(main):120:0> module M1
irb(main):121:1> end
=> nil
irb(main):122:0> module M2
irb(main):123:1> include M1
irb(main):124:1> end
=> M2
irb(main):125:0> class C1
irb(main):126:1> include M2
irb(main):127:1> end
=> C1
irb(main):128:0> C1.ancestors.select{|x|x.class==Module}
=> [M2, M1, Kernel]
I think that Chirag wanted to get only M2 and as you can see we get M1
as well. I personally think that there is no way to solve this. As far
as I know Ruby holds its ancestors internally in a plain list and
doesn't remember the hierarchy. Can someone tell more on this matter?
FireAphis
···
On Jul 25, 11:21 am, "Robert Dober" <robert.do...@gmail.com> wrote:
On 7/25/07, Chirag Mistry <chirag80b...@gmail.com> wrote:
> Hi
> I want to get a list of modules which are included directly in the class
> in ruby. Example: Suppose below are two modules and a class defined in
> ruby script.
> -------------------
> module M1
> ...
> end
> module M2
> ...
> end
> class MyClass
> include M1
> include M2
> ...
> end
> -------------------
> How can I get list of modules which are included directly in the class?
> Here in above example, M1 and M2 are only included in class MyClass so I
> only want a list which contains modules M1 and M2 for MyClass. If we
> call "MyClass.ancestors" which returns all the modules which are include
> directly or indirectly in this class and all parent class hierarchy that
> exactly I don't want to get.
Maybe my friend irb can help
irb(main):001:0> module M1; end
=> nil
irb(main):002:0> class C1; include M1 end
=> C1
irb(main):003:0> module M2; end
=> nil
irb(main):004:0> class C2 < C1; include M2 end
=> C2
irb(main):017:0> class Module
irb(main):018:1> def included_modules
irb(main):019:2> ancestors.select{|x|x.class==Module}
irb(main):020:2> end
irb(main):021:1> end
irb(main):022:0> C1.included_modules
=> [M1, Kernel]
irb(main):023:0> C2.included_modules
=> [M2, M1, Kernel]
You can get of Kernel of course if you do not want it to show up at the party.
HTH
Robert
--
I always knew that one day Smalltalk would replace Java.
I just didn't know it would be called Ruby
-- Kent Beck
There is a problem (him ! again ! Arrrrrrg (Monthy Python dixit (yeah
for Monthy Ruby !!! (sorry, I'll try to stop lisp-mod ;)))))
You should try this :
···
Le mercredi 01 août 2007 à 05:44 +0900, Wayne E. Seguin a écrit :
Chirag,
This is how I handle it in my applications:
# lib/ruby_extensions.rb
class Module
def included_modules
( ancestors - [ Kernel ] ).select { | x | x.class == Module &&
x != Kernel }
end
def directly_included_modules
ancestors - superclass.ancestors - [self]
end
def inherited_modules
superclass.included_modules - self.directly_included_modules
end
end
=======================================
irb:
>> module Module1; end
=>nil
>> class Class1; include Module1 end
=>Class1
>> module Module2; end
=>nil
>> class Class2 < Class1; include Module2 end
=>Class2
>> Class1.included_modules
=>[Module1]
>> Class2.included_modules
=>[Module2, Module1]
>> Class1.directly_included_modules
=>[Module1]
>> Class2.directly_included_modules
=>[Module2]
>> Class1.inherited_modules
=>
>> Class2.inherited_modules
=>[Module1]
Actually, I also allow for filtering out of other modules than Kernel
but that's not relevant here.
I sincerely hope this helps.
=======================================
(easy irb example paste:)
module Module1; end
class Class1; include Module1 end
module Module2; end
class Class2 < Class1; include Module2 end
(Not very much tested, but the idea is there, I think.)
Fred
···
Le 25 juillet à 08:44, FireAphis@gmail.com a écrit :
I think that Chirag wanted to get only M2 and as you can see we get M1
as well. I personally think that there is no way to solve this. As far
as I know Ruby holds its ancestors internally in a plain list and
doesn't remember the hierarchy. Can someone tell more on this matter?
--
I can imagine the moment Breaking out through the silence All the
things that we both might say And the heart it will not be denied
'Til we're both on the same damn side All the barriers blown away
(Peter Gabriel, Come Talk to Me)
>
> > Hi
>
> > I want to get a list of modules which are included directly in the class
> > in ruby. Example: Suppose below are two modules and a class defined in
> > ruby script.
> > -------------------
> > module M1
> > ...
> > end
> > module M2
> > ...
> > end
> > class MyClass
> > include M1
> > include M2
> > ...
> > end
> > -------------------
> > How can I get list of modules which are included directly in the class?
> > Here in above example, M1 and M2 are only included in class MyClass so I
> > only want a list which contains modules M1 and M2 for MyClass. If we
> > call "MyClass.ancestors" which returns all the modules which are include
> > directly or indirectly in this class and all parent class hierarchy that
> > exactly I don't want to get.
>
> > Regards
> > Chirag
> > --
> > Posted viahttp://www.ruby-forum.com/.
>
> Maybe my friend irb can help
> irb(main):001:0> module M1; end
> => nil
> irb(main):002:0> class C1; include M1 end
> => C1
> irb(main):003:0> module M2; end
> => nil
> irb(main):004:0> class C2 < C1; include M2 end
> => C2
> irb(main):017:0> class Module
> irb(main):018:1> def included_modules
> irb(main):019:2> ancestors.select{|x|x.class==Module}
> irb(main):020:2> end
> irb(main):021:1> end
> irb(main):022:0> C1.included_modules
> => [M1, Kernel]
> irb(main):023:0> C2.included_modules
> => [M2, M1, Kernel]
>
> You can get of Kernel of course if you do not want it to show up at the party.
> HTH
> Robert
>
> --
> I always knew that one day Smalltalk would replace Java.
> I just didn't know it would be called Ruby
> -- Kent Beck
I don't think that it answers the question. Look at the following
example:
irb(main):120:0> module M1
irb(main):121:1> end
=> nil
irb(main):122:0> module M2
irb(main):123:1> include M1
irb(main):124:1> end
=> M2
irb(main):125:0> class C1
irb(main):126:1> include M2
irb(main):127:1> end
=> C1
irb(main):128:0> C1.ancestors.select{|x|x.class==Module}
=> [M2, M1, Kernel]
I think that Chirag wanted to get only M2 and as you can see we get M1
as well.
What!!! Do I have to read the post in oder to answer now???
My bad you are right indeed.
I personally think that there is no way to solve this. As far
as I know Ruby holds its ancestors internally in a plain list and
doesn't remember the hierarchy. Can someone tell more on this matter?
That is indeed more challenging
···
On 7/25/07, FireAphis@gmail.com <FireAphis@gmail.com> wrote:
On Jul 25, 11:21 am, "Robert Dober" <robert.do...@gmail.com> wrote:
> On 7/25/07, Chirag Mistry <chirag80b...@gmail.com> wrote:
FireAphis
--
I always knew that one day Smalltalk would replace Java.
I just didn't know it would be called Ruby
-- Kent Beck
Good point. Any ideas on a better way?
Although if you're including twice like that the design is most likely flawed and needs a re-factoring?
···
On Aug 01, 2007, at 08:56 , dohzya wrote:
There is a problem (him ! again ! Arrrrrrg (Monthy Python dixit (yeah
for Monthy Ruby !!! (sorry, I'll try to stop lisp-mod ;)))))
You should try this :
---
module Module1; end
class Class1; include Module1 end
module Module2; end
class Class2 < Class1; include Module1 ; include Module2 end
Class1.included_modules
Class2.included_modules
Class1.directly_included_modules
Class2.directly_included_modules # see this result
Thank you very much for this feedback. After thinking about it, here is my take on this:
We include Module1 in Class1 and so from inheritence this implies that Class2 does not actually include Module1 directly, since it has already been included. Hence including Module1 in Class2 is effectively a no-op.
This makes semantic sense, also: "directly_included_modules" should be the modules that self includes which the superclass does not. In this light Module1 is not directly included so my code does what is expected.
(Also, for the record, Module already has an included_modules method, but I am overwriting because I don't want Kernel listed for my purposes)
(Thanks to Mark Josef for helping me with this idea)
···
On Aug 01, 2007, at 08:56 , dohzya wrote:
Le mercredi 01 août 2007 à 05:44 +0900, Wayne E. Seguin a écrit :
<snip>
There is a problem (him ! again ! Arrrrrrg (Monthy Python dixit (yeah
for Monthy Ruby !!! (sorry, I'll try to stop lisp-mod ;)))))
You should try this :
---
module Module1; end
class Class1; include Module1 end
module Module2; end
class Class2 < Class1; include Module1 ; include Module2 end
Class1.included_modules
Class2.included_modules
Class1.directly_included_modules
Class2.directly_included_modules # see this result
# > I think that Chirag wanted to get only M2 and as you can
# see we get M1 as well.
# What!!! Do I have to read the post in oder to answer now???
···
From: Robert Dober [mailto:robert.dober@gmail.com]
# On 7/25/07, FireAphis@gmail.com <FireAphis@gmail.com> wrote:
#
# My bad you are right indeed.
#
# > I personally think that there is no way to solve this. As far
# > as I know Ruby holds its ancestors internally in a plain list and
# > doesn't remember the hierarchy. Can someone tell more on
# this matter?
# That is indeed more challenging
From: Robert Dober [mailto:robert.dober@gmail.com]
# p C2.ancestors - (Class.new.ancestors + [C2])
Hi
Thanks for the reply. I have looked all the solution but all above
solution also includes modules which are included indirectly. I wants
list of modules which are included directly. See below example.
E.g.
···
----
module IN
end
module M1
include IN
end
module M2
include IN
end
class C
include M1
include M2
...
end
----
If we try above solution then I will get M1, M2, IN and Kernel. But
I want list which contains M1 and M2 only because these both are
included directly in class C.
Thank you very much for this feedback. After thinking about it, here
is my take on this:
We include Module1 in Class1 and so from inheritence this implies
that Class2 does not actually include Module1 directly, since it has
already been included. Hence including Module1 in Class2 is
effectively a no-op.
This makes semantic sense, also: "directly_included_modules" should
be the modules that self includes which the superclass does not. In
this light Module1 is not directly included so my code does what is
expected.
(Also, for the record, Module already has an included_modules method,
but I am overwriting because I don't want Kernel listed for my purposes)
(Thanks to Mark Josef for helping me with this idea)
--
Wayne E. Seguin
Sr. Systems Architect & Systems Admin
wayneseguin@gmail.com
Thanks
Indeed, it's comparable with the difference between 'define' and
'overload' (it isn't?)... moreover it's an overloading with same
method(s)
(I'm sorry if I'm repeating anyone, it's hard for me to express myself
and understand correctly in English... I'm working in this way)
But this is just to say I missed the obvious with meta-programming
inside the Module class :
class Module
alias orig_include include
def directly_included_modules @d_i_m ||
end
def include(m) @d_i_m ||= @d_i_m << m
orig_include m
end
end
(Maybe some 'freeze'ing could be in order, too.)
Fred
···
Le 25 juillet à 11:32, Peña, Botp a écrit :
FredSenault's previous post should give a hint
--
Love, I don't like to see so much pain So much wasted and this moment
keeps slipping away I get so tired of working so hard for out survival
I look to the time with you to keep me awake and alive
(Peter Gabriel, In Your Eyes)
# Peña, Botp wrote:
# > From: Robert Dober [mailto:robert.dober@gmail.com]
# > # p C2.ancestors - (Class.new.ancestors + [C2])
# E.g.
# ----
# module IN
# end
···
From: Chirag Mistry [mailto:chirag80bece@gmail.com]
#
# module M1
# include IN
# end
#
# module M2
# include IN
# end
#
# class C
# include M1
# include M2
# ...
# end
# ----
# If we try above solution then I will get M1, M2, IN and
# Kernel. But
# I want list which contains M1 and M2 only because these both are
# included directly in class C.
again, you can do fred's technique or
you can do plain subtraction. get the included modules of each and subtract it from the main...