Skip to content

Instantly share code, notes, and snippets.

@schnittchen
Created October 13, 2012 15:53
Show Gist options
  • Save schnittchen/3885102 to your computer and use it in GitHub Desktop.
Save schnittchen/3885102 to your computer and use it in GitHub Desktop.
A Ruby quirk with include. Quite annoying.
module A
module B
end
module Wrapper
module C
end
end
#Cite:
#When this module is included in another, Ruby calls append_features in this
#module, passing it the receiving module in mod. Ruby’s default
#implementation is to add the constants, methods, and module variables of
#this module to mod if this module has not already been added to mod or one
#of its ancestors. See also Module#include.
#But it's not that easy...
include Wrapper
end
p A.constants # => [:B, :Wrapper, :C]
p A::B # => A::B
p A::C # => A::Wrapper::C
module A
p B # => A::B
end
module A
p C # => A::Wrapper::C
end
module A
module Bracket
p B # => A::B
#p C (see bottom)
end
end
# Manual constant copying, from A::Wrapper
module X
A::Wrapper.constants.each do |sym|
const_set sym, A::Wrapper.const_get(sym)
end
p C # => A::Wrapper::C
# Quirk 1:
p defined?(B) # => nil
end
# Manual constant copying, from A. Works as well.
module Y
A.constants.each do |sym|
const_set sym, A.const_get(sym)
end
p B # => A::B
p C # => A::Wrapper::C
end
# This was a surprise to me:
module A
module Bracket
# Quirk 2:
p C #raises uninitialized constant A::Bracket::C (NameError)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment