Skip to content

Instantly share code, notes, and snippets.

@morhekil
Created May 28, 2015 23:48
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 morhekil/003732760c9ef80ceda9 to your computer and use it in GitHub Desktop.
Save morhekil/003732760c9ef80ceda9 to your computer and use it in GitHub Desktop.
ruby extend vs include
#
# <<<--- helpers to explore lookup chain
#
def method_lookup_chain(obj, result = [obj.singleton_class])
if obj.instance_of? Class
return add_modules(result) if result.last == BasicObject.singleton_class
r = result.last.superclass
method_lookup_chain(obj, result << r)
else
return result + obj.class.ancestors
end
end
def add_modules(klasses)
r = []
klasses.each_with_index do |k, i|
r << k
next if k == klasses.last
r << (k.included_modules - klasses[i+1].included_modules)
end
r.flatten
end
#
# helpers --->>>
#
module Probe
def self.extended(klass)
puts "probe extended #{klass}"
end
def self.included(klass)
puts "probe included into #{klass}"
end
end
class Target1
extend Probe
end
class Target2
class << self
include Probe
end
end
[Target1, Target1.singleton_class, Target2, Target2.singleton_class].each do |x|
puts "#{x}:"
puts "\tIncludes: " + x.included_modules.join(', ')
puts "\tLookup: " + method_lookup_chain(x).join(', ')
end
=begin
% ruby -v
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin14.0]
% ruby test.rb
probe extended Target1
probe included into #<Class:Target2>
Target1:
Includes: Kernel
Lookup: #<Class:Target1>, Probe, #<Class:Object>, #<Class:BasicObject>
#<Class:Target1>:
Includes: Probe, Kernel
Lookup: #<Class:#<Class:Target1>>, #<Class:#<Class:Object>>, #<Class:#<Class:BasicObject>>, #<Class:Class>, #<Class:Module>, #<Class:Object>, #<Class:BasicObject>
Target2:
Includes: Kernel
Lookup: #<Class:Target2>, Probe, #<Class:Object>, #<Class:BasicObject>
#<Class:Target2>:
Includes: Probe, Kernel
Lookup: #<Class:#<Class:Target2>>, #<Class:#<Class:Object>>, #<Class:#<Class:BasicObject>>, #<Class:Class>, #<Class:Module>, #<Class:Object>, #<Class:BasicObject>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment