Last active
May 14, 2019 19:38
-
-
Save cpruitt/63cd9063953f4ba46bd642c69babd2c1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Including this module should let us check an instance to see if a particular | |
| # method is redundant and can be removed. Redundant methods return the same result | |
| # as the same method defined by a superclass or inherited module | |
| module RedundancyChecker | |
| def check_redundant_method(meth) | |
| result = if self.class.method_defined?(meth, false) | |
| [{class_name: self.class, result: send(meth)}] | |
| else | |
| [] | |
| end | |
| ancestor_list = self.class.ancestors.tap(&:shift) | |
| result = ancestor_list.inject(result) { |result, klass| | |
| result << if klass.method_defined?(meth, false) | |
| {class_name: klass, result: klass.instance_method(meth).bind(self).call } | |
| else | |
| nil | |
| end | |
| }.compact | |
| self_result = self.send(meth) | |
| redundant = result.take_while { |itm| itm[:result] == self_result } | |
| redundant.collect {|h| h[:class_name]}.tap(&:pop) | |
| end | |
| end | |
| # Set up a bunch of classes for inheritance examples. | |
| class AppController | |
| include RedundancyChecker | |
| def likes_tacos | |
| return true | |
| end | |
| end | |
| class CleanController < AppController | |
| end | |
| class OverrideController < AppController | |
| def likes_tacos | |
| return false | |
| end | |
| end | |
| class ResetController < OverrideController | |
| def likes_tacos | |
| return true | |
| end | |
| end | |
| class ResetNoChangeController < OverrideController | |
| def likes_tacos | |
| return false | |
| end | |
| end | |
| module MixinOverride | |
| def likes_tacos | |
| return false | |
| end | |
| end | |
| class MixinOverrideController < AppController | |
| include MixinOverride | |
| end | |
| class ResetMixinController < MixinOverrideController | |
| def likes_tacos | |
| return true | |
| end | |
| end | |
| class InheritFromHasMixinController < MixinOverrideController | |
| def likes_tacos | |
| return true | |
| end | |
| end | |
| class InheritOtherFromHasMixinController < MixinOverrideController | |
| def likes_tacos | |
| return false | |
| end | |
| end | |
| module MixinReset | |
| def likes_tacos | |
| return true | |
| end | |
| end | |
| class MixinResetMixinController < MixinOverrideController | |
| include MixinReset | |
| end | |
| class OverrideMixinResetMixinController < MixinResetMixinController | |
| include MixinReset | |
| def likes_tacos | |
| return false | |
| end | |
| end | |
| class DoesSomethingController < OverrideMixinResetMixinController | |
| def likes_tacos | |
| return true | |
| end | |
| end | |
| class DoesSomethingElseController < DoesSomethingController | |
| def likes_tacos | |
| return false | |
| end | |
| end | |
| class MoreDoesSomethingController < DoesSomethingElseController | |
| def likes_tacos | |
| return false | |
| end | |
| end | |
| class DoesNothingController < MoreDoesSomethingController | |
| end | |
| class MoreDoesNothingController < DoesNothingController | |
| end | |
| class DeepInheritController < MoreDoesNothingController | |
| include MixinReset | |
| def likes_tacos | |
| return false | |
| end | |
| end | |
| # Loop through all our example classes to see if we're redundantly liking tacos. | |
| [ | |
| AppController, | |
| CleanController, | |
| OverrideController, | |
| ResetController, | |
| ResetNoChangeController, | |
| MixinOverrideController, | |
| ResetMixinController, | |
| InheritFromHasMixinController, | |
| InheritOtherFromHasMixinController, | |
| MixinResetMixinController, | |
| OverrideMixinResetMixinController, | |
| DoesSomethingController, | |
| DoesSomethingElseController, | |
| MoreDoesSomethingController, | |
| DoesNothingController, | |
| MoreDoesNothingController, | |
| DeepInheritController, | |
| ].each do |klass| | |
| puts "Checking #{klass} for redundant '#likes_tacos' definition" | |
| instance = klass.new | |
| redundants = instance.check_redundant_method(:likes_tacos) | |
| if redundants.empty? | |
| puts "Looks good. Carry on." | |
| else | |
| puts "These classes / modules have redundent method defitions." | |
| puts "Removing them should have no impact on #{klass}:" | |
| puts redundants.collect{ |a| "- #{a}\n"} | |
| end | |
| puts "----------\n\n" | |
| end | |
| puts "Done. Godspeed." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment