Let `super` call the parent class over an included module





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







3















I have class Boy that inherits class Person, and includes module Bipedal. Both Person and Bipedal have versions of #two_legs.



module Bipedal
def two_legs(name)
puts "#{name} has exactly two limbs used for walking."
end
end

class Person
def two_legs(name)
puts "#{name} has two human legs."
end
end

class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end

def two_legs
super(@name)
end
end


Since the Bipedal module is included in Boy, Bipedal#two_legs takes precedence over the Person#two_legs. When I call super on a Boy instance, the module Bipedal takes precedence over the parent class Person.



johnny = Boy.new('Johnny')
johnny.two_legs
# >> "Johnny has exactly two limbs used for walking."


I want to use one version in one place and the other in another. Bipedal has other stuff, so I can't comment out include Bipedal. Is there some standard way to let Boy#two_legs or super to use the parent class version instead of the module version as follows?



johnny.two_legs
# >> "Johnny has two human legs."


I came up with this:



Boy.superclass.instance_method(:two_legs).bind(self).call(@name)


which works in place of super(@name), but is more complicated than I was expecting.



Again, the question is, is there a standard way to force the parent class to take precedence over the module when calling super?










share|improve this question

























  • Your use case is not clear. If you want to switch between different methods, why can't they be named as different methods? Why do they have to be named the same? Can you pass some argument to the method, depending on which the method behaves differently?

    – sawa
    Nov 27 '18 at 7:05











  • Suppose I am not in charge of the module or the superclass.

    – globewalldesk
    Nov 27 '18 at 13:59




















3















I have class Boy that inherits class Person, and includes module Bipedal. Both Person and Bipedal have versions of #two_legs.



module Bipedal
def two_legs(name)
puts "#{name} has exactly two limbs used for walking."
end
end

class Person
def two_legs(name)
puts "#{name} has two human legs."
end
end

class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end

def two_legs
super(@name)
end
end


Since the Bipedal module is included in Boy, Bipedal#two_legs takes precedence over the Person#two_legs. When I call super on a Boy instance, the module Bipedal takes precedence over the parent class Person.



johnny = Boy.new('Johnny')
johnny.two_legs
# >> "Johnny has exactly two limbs used for walking."


I want to use one version in one place and the other in another. Bipedal has other stuff, so I can't comment out include Bipedal. Is there some standard way to let Boy#two_legs or super to use the parent class version instead of the module version as follows?



johnny.two_legs
# >> "Johnny has two human legs."


I came up with this:



Boy.superclass.instance_method(:two_legs).bind(self).call(@name)


which works in place of super(@name), but is more complicated than I was expecting.



Again, the question is, is there a standard way to force the parent class to take precedence over the module when calling super?










share|improve this question

























  • Your use case is not clear. If you want to switch between different methods, why can't they be named as different methods? Why do they have to be named the same? Can you pass some argument to the method, depending on which the method behaves differently?

    – sawa
    Nov 27 '18 at 7:05











  • Suppose I am not in charge of the module or the superclass.

    – globewalldesk
    Nov 27 '18 at 13:59
















3












3








3








I have class Boy that inherits class Person, and includes module Bipedal. Both Person and Bipedal have versions of #two_legs.



module Bipedal
def two_legs(name)
puts "#{name} has exactly two limbs used for walking."
end
end

class Person
def two_legs(name)
puts "#{name} has two human legs."
end
end

class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end

def two_legs
super(@name)
end
end


Since the Bipedal module is included in Boy, Bipedal#two_legs takes precedence over the Person#two_legs. When I call super on a Boy instance, the module Bipedal takes precedence over the parent class Person.



johnny = Boy.new('Johnny')
johnny.two_legs
# >> "Johnny has exactly two limbs used for walking."


I want to use one version in one place and the other in another. Bipedal has other stuff, so I can't comment out include Bipedal. Is there some standard way to let Boy#two_legs or super to use the parent class version instead of the module version as follows?



johnny.two_legs
# >> "Johnny has two human legs."


I came up with this:



Boy.superclass.instance_method(:two_legs).bind(self).call(@name)


which works in place of super(@name), but is more complicated than I was expecting.



Again, the question is, is there a standard way to force the parent class to take precedence over the module when calling super?










share|improve this question
















I have class Boy that inherits class Person, and includes module Bipedal. Both Person and Bipedal have versions of #two_legs.



module Bipedal
def two_legs(name)
puts "#{name} has exactly two limbs used for walking."
end
end

class Person
def two_legs(name)
puts "#{name} has two human legs."
end
end

class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end

def two_legs
super(@name)
end
end


Since the Bipedal module is included in Boy, Bipedal#two_legs takes precedence over the Person#two_legs. When I call super on a Boy instance, the module Bipedal takes precedence over the parent class Person.



johnny = Boy.new('Johnny')
johnny.two_legs
# >> "Johnny has exactly two limbs used for walking."


I want to use one version in one place and the other in another. Bipedal has other stuff, so I can't comment out include Bipedal. Is there some standard way to let Boy#two_legs or super to use the parent class version instead of the module version as follows?



johnny.two_legs
# >> "Johnny has two human legs."


I came up with this:



Boy.superclass.instance_method(:two_legs).bind(self).call(@name)


which works in place of super(@name), but is more complicated than I was expecting.



Again, the question is, is there a standard way to force the parent class to take precedence over the module when calling super?







ruby inheritance superclass






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 30 '18 at 0:25









anothermh

3,37931733




3,37931733










asked Nov 27 '18 at 0:56









globewalldeskglobewalldesk

329112




329112













  • Your use case is not clear. If you want to switch between different methods, why can't they be named as different methods? Why do they have to be named the same? Can you pass some argument to the method, depending on which the method behaves differently?

    – sawa
    Nov 27 '18 at 7:05











  • Suppose I am not in charge of the module or the superclass.

    – globewalldesk
    Nov 27 '18 at 13:59





















  • Your use case is not clear. If you want to switch between different methods, why can't they be named as different methods? Why do they have to be named the same? Can you pass some argument to the method, depending on which the method behaves differently?

    – sawa
    Nov 27 '18 at 7:05











  • Suppose I am not in charge of the module or the superclass.

    – globewalldesk
    Nov 27 '18 at 13:59



















Your use case is not clear. If you want to switch between different methods, why can't they be named as different methods? Why do they have to be named the same? Can you pass some argument to the method, depending on which the method behaves differently?

– sawa
Nov 27 '18 at 7:05





Your use case is not clear. If you want to switch between different methods, why can't they be named as different methods? Why do they have to be named the same? Can you pass some argument to the method, depending on which the method behaves differently?

– sawa
Nov 27 '18 at 7:05













Suppose I am not in charge of the module or the superclass.

– globewalldesk
Nov 27 '18 at 13:59







Suppose I am not in charge of the module or the superclass.

– globewalldesk
Nov 27 '18 at 13:59














3 Answers
3






active

oldest

votes


















2














One could use the method Method#super_method twice. That being a garden-variety Ruby method, I believe it would qualify as a "standard way" to let Boy#two_legs invoke Person#two_legs rather than Bipedal#two_legs.



class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end
def two_legs
method(:two_legs).super_method.super_method.call(@name)
end
end

willie = Boy.new('Willie')
willie.two_legs
Willie has two human legs.


Note the following.



willie.method(:two_legs).super_method.owner
#=> Bipedal
willie.method(:two_legs).super_method.super_method.owner
#=> Person





share|improve this answer


























  • This one just works!

    – globewalldesk
    Nov 29 '18 at 14:27



















3














No, there is no standard way to force a call to super to walk the ancestors in a specific order. They are walked in a pre-defined order. Take a look at the documentation on calling methods:




When you send a message, Ruby looks up the method that matches the name of the message for the receiver. Methods are stored in classes and modules so method lookup walks these, not the objects themselves.



Here is the order of method lookup for the receiver's class or module R:




  • The prepended modules of R in reverse order

  • For a matching method in R

  • The included modules of R in reverse order


If R is a class with a superclass, this is repeated with R's superclass until a method is found.



Once a match is found method lookup stops.




Since your class Boy includes the module Bipedal directly, and since included modules are searched before the superclass, and since searching stops once a match is found, the superclass Person is never checked.



The same is true when using refinements because the lookup always hits included modules before it checks the superclass.



If you move include Bipedal into the Person class then it will work the way you expect because Boy does not include a module directly, so it will eventually search the superclass where it will find the defined method.



There may be other creative ways you can accomplish this goal, like the Boy.superclass... example you gave, but you asked if it's possible to change the lookup behavior when calling super and the answer is no per the documentation.






share|improve this answer


























  • Shame (or not depending how much sanity you like) that you can't edit SomeModule.ancestors.

    – mu is too short
    Nov 27 '18 at 7:18











  • I did a quick test, and defining a class method self.ancestors in the child class with the desired order does not work. super must use some other means of looking up the ancestors. You may be able to find some more info in the spec for super.

    – anothermh
    Nov 27 '18 at 19:34



















2














I don't think you can change how super works and you can't "super super" to skip an ancestor but you can use a different ancestor. If you're just including Bipedal for some of its methods and want to skip a few of them then you could do something like this:



SemiBipedal = Bipedal.dup
SemiBipedal.remove_method(:two_legs)

class Boy < Person
include SemiBipedal
#...
end


Of course johnny.is_a? Bipedal won't be true anymore and Boy.ancestors will have SemiBipedal instead of Bipedal at index 1 but that might not matter.






share|improve this answer
























  • I love this idea, but when I typed it in, I couldn’t get it to work. I get “private method ‘remove_method’ called for SemiBipedal:Module (NoMethodError)”.

    – globewalldesk
    Nov 27 '18 at 13:41











  • The only place that remove_method seems to work is within the Bipedal module itself…

    – globewalldesk
    Nov 27 '18 at 13:51











  • Which version of Ruby are you using? remove_method doesn't appear to be private in 2.5.3. You can always SemiBipedal.send(:remove_method, :two_legs) or module SemiBipedal; remove_method :two_legs; end to kludge around that.

    – mu is too short
    Nov 27 '18 at 19:03













  • I was using 2.4.0 but I updated it to 2.5.3, re-ran the code (copied straight from yours) and it still gives me that private method error. SemiBipedal.send(:remove_method, :two_legs) works great. Maybe the most straightforward way is to skip an alias module and add Bipedal.send(:remove_method, :two_legs) directly to Boy, assuming Boy doesn't need the Bipedal version...

    – globewalldesk
    Nov 28 '18 at 0:21






  • 2





    But Bipedal.send(:remove_method, :two_legs) modifies Bipedal so everything that uses the module will be affected, hence the copy of Bipedal (not alias) and removing two_legs from the copy.

    – mu is too short
    Nov 28 '18 at 0:36












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53491282%2flet-super-call-the-parent-class-over-an-included-module%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














One could use the method Method#super_method twice. That being a garden-variety Ruby method, I believe it would qualify as a "standard way" to let Boy#two_legs invoke Person#two_legs rather than Bipedal#two_legs.



class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end
def two_legs
method(:two_legs).super_method.super_method.call(@name)
end
end

willie = Boy.new('Willie')
willie.two_legs
Willie has two human legs.


Note the following.



willie.method(:two_legs).super_method.owner
#=> Bipedal
willie.method(:two_legs).super_method.super_method.owner
#=> Person





share|improve this answer


























  • This one just works!

    – globewalldesk
    Nov 29 '18 at 14:27
















2














One could use the method Method#super_method twice. That being a garden-variety Ruby method, I believe it would qualify as a "standard way" to let Boy#two_legs invoke Person#two_legs rather than Bipedal#two_legs.



class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end
def two_legs
method(:two_legs).super_method.super_method.call(@name)
end
end

willie = Boy.new('Willie')
willie.two_legs
Willie has two human legs.


Note the following.



willie.method(:two_legs).super_method.owner
#=> Bipedal
willie.method(:two_legs).super_method.super_method.owner
#=> Person





share|improve this answer


























  • This one just works!

    – globewalldesk
    Nov 29 '18 at 14:27














2












2








2







One could use the method Method#super_method twice. That being a garden-variety Ruby method, I believe it would qualify as a "standard way" to let Boy#two_legs invoke Person#two_legs rather than Bipedal#two_legs.



class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end
def two_legs
method(:two_legs).super_method.super_method.call(@name)
end
end

willie = Boy.new('Willie')
willie.two_legs
Willie has two human legs.


Note the following.



willie.method(:two_legs).super_method.owner
#=> Bipedal
willie.method(:two_legs).super_method.super_method.owner
#=> Person





share|improve this answer















One could use the method Method#super_method twice. That being a garden-variety Ruby method, I believe it would qualify as a "standard way" to let Boy#two_legs invoke Person#two_legs rather than Bipedal#two_legs.



class Boy < Person
include Bipedal
attr_accessor :name
def initialize(name)
@name = name
end
def two_legs
method(:two_legs).super_method.super_method.call(@name)
end
end

willie = Boy.new('Willie')
willie.two_legs
Willie has two human legs.


Note the following.



willie.method(:two_legs).super_method.owner
#=> Bipedal
willie.method(:two_legs).super_method.super_method.owner
#=> Person






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 29 '18 at 5:19

























answered Nov 28 '18 at 22:04









Cary SwovelandCary Swoveland

71.3k54167




71.3k54167













  • This one just works!

    – globewalldesk
    Nov 29 '18 at 14:27



















  • This one just works!

    – globewalldesk
    Nov 29 '18 at 14:27

















This one just works!

– globewalldesk
Nov 29 '18 at 14:27





This one just works!

– globewalldesk
Nov 29 '18 at 14:27













3














No, there is no standard way to force a call to super to walk the ancestors in a specific order. They are walked in a pre-defined order. Take a look at the documentation on calling methods:




When you send a message, Ruby looks up the method that matches the name of the message for the receiver. Methods are stored in classes and modules so method lookup walks these, not the objects themselves.



Here is the order of method lookup for the receiver's class or module R:




  • The prepended modules of R in reverse order

  • For a matching method in R

  • The included modules of R in reverse order


If R is a class with a superclass, this is repeated with R's superclass until a method is found.



Once a match is found method lookup stops.




Since your class Boy includes the module Bipedal directly, and since included modules are searched before the superclass, and since searching stops once a match is found, the superclass Person is never checked.



The same is true when using refinements because the lookup always hits included modules before it checks the superclass.



If you move include Bipedal into the Person class then it will work the way you expect because Boy does not include a module directly, so it will eventually search the superclass where it will find the defined method.



There may be other creative ways you can accomplish this goal, like the Boy.superclass... example you gave, but you asked if it's possible to change the lookup behavior when calling super and the answer is no per the documentation.






share|improve this answer


























  • Shame (or not depending how much sanity you like) that you can't edit SomeModule.ancestors.

    – mu is too short
    Nov 27 '18 at 7:18











  • I did a quick test, and defining a class method self.ancestors in the child class with the desired order does not work. super must use some other means of looking up the ancestors. You may be able to find some more info in the spec for super.

    – anothermh
    Nov 27 '18 at 19:34
















3














No, there is no standard way to force a call to super to walk the ancestors in a specific order. They are walked in a pre-defined order. Take a look at the documentation on calling methods:




When you send a message, Ruby looks up the method that matches the name of the message for the receiver. Methods are stored in classes and modules so method lookup walks these, not the objects themselves.



Here is the order of method lookup for the receiver's class or module R:




  • The prepended modules of R in reverse order

  • For a matching method in R

  • The included modules of R in reverse order


If R is a class with a superclass, this is repeated with R's superclass until a method is found.



Once a match is found method lookup stops.




Since your class Boy includes the module Bipedal directly, and since included modules are searched before the superclass, and since searching stops once a match is found, the superclass Person is never checked.



The same is true when using refinements because the lookup always hits included modules before it checks the superclass.



If you move include Bipedal into the Person class then it will work the way you expect because Boy does not include a module directly, so it will eventually search the superclass where it will find the defined method.



There may be other creative ways you can accomplish this goal, like the Boy.superclass... example you gave, but you asked if it's possible to change the lookup behavior when calling super and the answer is no per the documentation.






share|improve this answer


























  • Shame (or not depending how much sanity you like) that you can't edit SomeModule.ancestors.

    – mu is too short
    Nov 27 '18 at 7:18











  • I did a quick test, and defining a class method self.ancestors in the child class with the desired order does not work. super must use some other means of looking up the ancestors. You may be able to find some more info in the spec for super.

    – anothermh
    Nov 27 '18 at 19:34














3












3








3







No, there is no standard way to force a call to super to walk the ancestors in a specific order. They are walked in a pre-defined order. Take a look at the documentation on calling methods:




When you send a message, Ruby looks up the method that matches the name of the message for the receiver. Methods are stored in classes and modules so method lookup walks these, not the objects themselves.



Here is the order of method lookup for the receiver's class or module R:




  • The prepended modules of R in reverse order

  • For a matching method in R

  • The included modules of R in reverse order


If R is a class with a superclass, this is repeated with R's superclass until a method is found.



Once a match is found method lookup stops.




Since your class Boy includes the module Bipedal directly, and since included modules are searched before the superclass, and since searching stops once a match is found, the superclass Person is never checked.



The same is true when using refinements because the lookup always hits included modules before it checks the superclass.



If you move include Bipedal into the Person class then it will work the way you expect because Boy does not include a module directly, so it will eventually search the superclass where it will find the defined method.



There may be other creative ways you can accomplish this goal, like the Boy.superclass... example you gave, but you asked if it's possible to change the lookup behavior when calling super and the answer is no per the documentation.






share|improve this answer















No, there is no standard way to force a call to super to walk the ancestors in a specific order. They are walked in a pre-defined order. Take a look at the documentation on calling methods:




When you send a message, Ruby looks up the method that matches the name of the message for the receiver. Methods are stored in classes and modules so method lookup walks these, not the objects themselves.



Here is the order of method lookup for the receiver's class or module R:




  • The prepended modules of R in reverse order

  • For a matching method in R

  • The included modules of R in reverse order


If R is a class with a superclass, this is repeated with R's superclass until a method is found.



Once a match is found method lookup stops.




Since your class Boy includes the module Bipedal directly, and since included modules are searched before the superclass, and since searching stops once a match is found, the superclass Person is never checked.



The same is true when using refinements because the lookup always hits included modules before it checks the superclass.



If you move include Bipedal into the Person class then it will work the way you expect because Boy does not include a module directly, so it will eventually search the superclass where it will find the defined method.



There may be other creative ways you can accomplish this goal, like the Boy.superclass... example you gave, but you asked if it's possible to change the lookup behavior when calling super and the answer is no per the documentation.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 27 '18 at 7:50

























answered Nov 27 '18 at 3:35









anothermhanothermh

3,37931733




3,37931733













  • Shame (or not depending how much sanity you like) that you can't edit SomeModule.ancestors.

    – mu is too short
    Nov 27 '18 at 7:18











  • I did a quick test, and defining a class method self.ancestors in the child class with the desired order does not work. super must use some other means of looking up the ancestors. You may be able to find some more info in the spec for super.

    – anothermh
    Nov 27 '18 at 19:34



















  • Shame (or not depending how much sanity you like) that you can't edit SomeModule.ancestors.

    – mu is too short
    Nov 27 '18 at 7:18











  • I did a quick test, and defining a class method self.ancestors in the child class with the desired order does not work. super must use some other means of looking up the ancestors. You may be able to find some more info in the spec for super.

    – anothermh
    Nov 27 '18 at 19:34

















Shame (or not depending how much sanity you like) that you can't edit SomeModule.ancestors.

– mu is too short
Nov 27 '18 at 7:18





Shame (or not depending how much sanity you like) that you can't edit SomeModule.ancestors.

– mu is too short
Nov 27 '18 at 7:18













I did a quick test, and defining a class method self.ancestors in the child class with the desired order does not work. super must use some other means of looking up the ancestors. You may be able to find some more info in the spec for super.

– anothermh
Nov 27 '18 at 19:34





I did a quick test, and defining a class method self.ancestors in the child class with the desired order does not work. super must use some other means of looking up the ancestors. You may be able to find some more info in the spec for super.

– anothermh
Nov 27 '18 at 19:34











2














I don't think you can change how super works and you can't "super super" to skip an ancestor but you can use a different ancestor. If you're just including Bipedal for some of its methods and want to skip a few of them then you could do something like this:



SemiBipedal = Bipedal.dup
SemiBipedal.remove_method(:two_legs)

class Boy < Person
include SemiBipedal
#...
end


Of course johnny.is_a? Bipedal won't be true anymore and Boy.ancestors will have SemiBipedal instead of Bipedal at index 1 but that might not matter.






share|improve this answer
























  • I love this idea, but when I typed it in, I couldn’t get it to work. I get “private method ‘remove_method’ called for SemiBipedal:Module (NoMethodError)”.

    – globewalldesk
    Nov 27 '18 at 13:41











  • The only place that remove_method seems to work is within the Bipedal module itself…

    – globewalldesk
    Nov 27 '18 at 13:51











  • Which version of Ruby are you using? remove_method doesn't appear to be private in 2.5.3. You can always SemiBipedal.send(:remove_method, :two_legs) or module SemiBipedal; remove_method :two_legs; end to kludge around that.

    – mu is too short
    Nov 27 '18 at 19:03













  • I was using 2.4.0 but I updated it to 2.5.3, re-ran the code (copied straight from yours) and it still gives me that private method error. SemiBipedal.send(:remove_method, :two_legs) works great. Maybe the most straightforward way is to skip an alias module and add Bipedal.send(:remove_method, :two_legs) directly to Boy, assuming Boy doesn't need the Bipedal version...

    – globewalldesk
    Nov 28 '18 at 0:21






  • 2





    But Bipedal.send(:remove_method, :two_legs) modifies Bipedal so everything that uses the module will be affected, hence the copy of Bipedal (not alias) and removing two_legs from the copy.

    – mu is too short
    Nov 28 '18 at 0:36
















2














I don't think you can change how super works and you can't "super super" to skip an ancestor but you can use a different ancestor. If you're just including Bipedal for some of its methods and want to skip a few of them then you could do something like this:



SemiBipedal = Bipedal.dup
SemiBipedal.remove_method(:two_legs)

class Boy < Person
include SemiBipedal
#...
end


Of course johnny.is_a? Bipedal won't be true anymore and Boy.ancestors will have SemiBipedal instead of Bipedal at index 1 but that might not matter.






share|improve this answer
























  • I love this idea, but when I typed it in, I couldn’t get it to work. I get “private method ‘remove_method’ called for SemiBipedal:Module (NoMethodError)”.

    – globewalldesk
    Nov 27 '18 at 13:41











  • The only place that remove_method seems to work is within the Bipedal module itself…

    – globewalldesk
    Nov 27 '18 at 13:51











  • Which version of Ruby are you using? remove_method doesn't appear to be private in 2.5.3. You can always SemiBipedal.send(:remove_method, :two_legs) or module SemiBipedal; remove_method :two_legs; end to kludge around that.

    – mu is too short
    Nov 27 '18 at 19:03













  • I was using 2.4.0 but I updated it to 2.5.3, re-ran the code (copied straight from yours) and it still gives me that private method error. SemiBipedal.send(:remove_method, :two_legs) works great. Maybe the most straightforward way is to skip an alias module and add Bipedal.send(:remove_method, :two_legs) directly to Boy, assuming Boy doesn't need the Bipedal version...

    – globewalldesk
    Nov 28 '18 at 0:21






  • 2





    But Bipedal.send(:remove_method, :two_legs) modifies Bipedal so everything that uses the module will be affected, hence the copy of Bipedal (not alias) and removing two_legs from the copy.

    – mu is too short
    Nov 28 '18 at 0:36














2












2








2







I don't think you can change how super works and you can't "super super" to skip an ancestor but you can use a different ancestor. If you're just including Bipedal for some of its methods and want to skip a few of them then you could do something like this:



SemiBipedal = Bipedal.dup
SemiBipedal.remove_method(:two_legs)

class Boy < Person
include SemiBipedal
#...
end


Of course johnny.is_a? Bipedal won't be true anymore and Boy.ancestors will have SemiBipedal instead of Bipedal at index 1 but that might not matter.






share|improve this answer













I don't think you can change how super works and you can't "super super" to skip an ancestor but you can use a different ancestor. If you're just including Bipedal for some of its methods and want to skip a few of them then you could do something like this:



SemiBipedal = Bipedal.dup
SemiBipedal.remove_method(:two_legs)

class Boy < Person
include SemiBipedal
#...
end


Of course johnny.is_a? Bipedal won't be true anymore and Boy.ancestors will have SemiBipedal instead of Bipedal at index 1 but that might not matter.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 27 '18 at 7:17









mu is too shortmu is too short

355k58702677




355k58702677













  • I love this idea, but when I typed it in, I couldn’t get it to work. I get “private method ‘remove_method’ called for SemiBipedal:Module (NoMethodError)”.

    – globewalldesk
    Nov 27 '18 at 13:41











  • The only place that remove_method seems to work is within the Bipedal module itself…

    – globewalldesk
    Nov 27 '18 at 13:51











  • Which version of Ruby are you using? remove_method doesn't appear to be private in 2.5.3. You can always SemiBipedal.send(:remove_method, :two_legs) or module SemiBipedal; remove_method :two_legs; end to kludge around that.

    – mu is too short
    Nov 27 '18 at 19:03













  • I was using 2.4.0 but I updated it to 2.5.3, re-ran the code (copied straight from yours) and it still gives me that private method error. SemiBipedal.send(:remove_method, :two_legs) works great. Maybe the most straightforward way is to skip an alias module and add Bipedal.send(:remove_method, :two_legs) directly to Boy, assuming Boy doesn't need the Bipedal version...

    – globewalldesk
    Nov 28 '18 at 0:21






  • 2





    But Bipedal.send(:remove_method, :two_legs) modifies Bipedal so everything that uses the module will be affected, hence the copy of Bipedal (not alias) and removing two_legs from the copy.

    – mu is too short
    Nov 28 '18 at 0:36



















  • I love this idea, but when I typed it in, I couldn’t get it to work. I get “private method ‘remove_method’ called for SemiBipedal:Module (NoMethodError)”.

    – globewalldesk
    Nov 27 '18 at 13:41











  • The only place that remove_method seems to work is within the Bipedal module itself…

    – globewalldesk
    Nov 27 '18 at 13:51











  • Which version of Ruby are you using? remove_method doesn't appear to be private in 2.5.3. You can always SemiBipedal.send(:remove_method, :two_legs) or module SemiBipedal; remove_method :two_legs; end to kludge around that.

    – mu is too short
    Nov 27 '18 at 19:03













  • I was using 2.4.0 but I updated it to 2.5.3, re-ran the code (copied straight from yours) and it still gives me that private method error. SemiBipedal.send(:remove_method, :two_legs) works great. Maybe the most straightforward way is to skip an alias module and add Bipedal.send(:remove_method, :two_legs) directly to Boy, assuming Boy doesn't need the Bipedal version...

    – globewalldesk
    Nov 28 '18 at 0:21






  • 2





    But Bipedal.send(:remove_method, :two_legs) modifies Bipedal so everything that uses the module will be affected, hence the copy of Bipedal (not alias) and removing two_legs from the copy.

    – mu is too short
    Nov 28 '18 at 0:36

















I love this idea, but when I typed it in, I couldn’t get it to work. I get “private method ‘remove_method’ called for SemiBipedal:Module (NoMethodError)”.

– globewalldesk
Nov 27 '18 at 13:41





I love this idea, but when I typed it in, I couldn’t get it to work. I get “private method ‘remove_method’ called for SemiBipedal:Module (NoMethodError)”.

– globewalldesk
Nov 27 '18 at 13:41













The only place that remove_method seems to work is within the Bipedal module itself…

– globewalldesk
Nov 27 '18 at 13:51





The only place that remove_method seems to work is within the Bipedal module itself…

– globewalldesk
Nov 27 '18 at 13:51













Which version of Ruby are you using? remove_method doesn't appear to be private in 2.5.3. You can always SemiBipedal.send(:remove_method, :two_legs) or module SemiBipedal; remove_method :two_legs; end to kludge around that.

– mu is too short
Nov 27 '18 at 19:03







Which version of Ruby are you using? remove_method doesn't appear to be private in 2.5.3. You can always SemiBipedal.send(:remove_method, :two_legs) or module SemiBipedal; remove_method :two_legs; end to kludge around that.

– mu is too short
Nov 27 '18 at 19:03















I was using 2.4.0 but I updated it to 2.5.3, re-ran the code (copied straight from yours) and it still gives me that private method error. SemiBipedal.send(:remove_method, :two_legs) works great. Maybe the most straightforward way is to skip an alias module and add Bipedal.send(:remove_method, :two_legs) directly to Boy, assuming Boy doesn't need the Bipedal version...

– globewalldesk
Nov 28 '18 at 0:21





I was using 2.4.0 but I updated it to 2.5.3, re-ran the code (copied straight from yours) and it still gives me that private method error. SemiBipedal.send(:remove_method, :two_legs) works great. Maybe the most straightforward way is to skip an alias module and add Bipedal.send(:remove_method, :two_legs) directly to Boy, assuming Boy doesn't need the Bipedal version...

– globewalldesk
Nov 28 '18 at 0:21




2




2





But Bipedal.send(:remove_method, :two_legs) modifies Bipedal so everything that uses the module will be affected, hence the copy of Bipedal (not alias) and removing two_legs from the copy.

– mu is too short
Nov 28 '18 at 0:36





But Bipedal.send(:remove_method, :two_legs) modifies Bipedal so everything that uses the module will be affected, hence the copy of Bipedal (not alias) and removing two_legs from the copy.

– mu is too short
Nov 28 '18 at 0:36


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53491282%2flet-super-call-the-parent-class-over-an-included-module%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Wiesbaden

Marschland

Dieringhausen