Skip to content

Instantly share code, notes, and snippets.

@chrismo
Created December 7, 2012 18:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrismo/4235378 to your computer and use it in GitHub Desktop.
Save chrismo/4235378 to your computer and use it in GitHub Desktop.
idempotent alias_method_chain
.bundle
.rbenv-version
zz_gems
bin

Jay Fields discusses the 'stack level too deep' problem with alias_method and alias_method_chain if a file gets loaded twice (which is not uncommon in a large enough project). This is an attempt to workaround it.

bundle install
bundle exec ruby runner.rb

You can see the simple check for instance_methods.include? on the alias_method_chain for execute prevents the chaining from happening multiple times which causes the stack level too deep.

Bundler.require
class Base
def execute
puts 'base execute'
end
def fail
puts 'base fail'
end
end
require 'active_support/core_ext/module'
class Base
def execute_with_awesome
execute_without_awesome
puts '...now with awesome!'
end
def fail_with_awesome
fail_without_awesome
puts '...now with awesome!'
end
alias_method_chain :execute, :awesome unless instance_methods.include? :execute_without_awesome
alias_method_chain :fail, :awesome
end
source :rubygems
gem 'activesupport'
GEM
remote: http://rubygems.org/
specs:
activesupport (3.0.0)
PLATFORMS
ruby
DEPENDENCIES
activesupport
require File.dirname(__FILE__) + '/base'
# load twice to enable 'stack level too deep problem'
load File.dirname(__FILE__) + '/extension.rb'
load File.dirname(__FILE__) + '/extension.rb'
base = Base.new
base.execute
base.fail
@chrismo
Copy link
Author

chrismo commented Dec 7, 2012

1.8 stores method names in instance_methods as strings, not symbols.

@chrismo
Copy link
Author

chrismo commented Dec 7, 2012

private and protected methods won't show in instance_methods ... so ... may need to use those variants.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment