Skip to content

Instantly share code, notes, and snippets.

@rubiii
Created September 3, 2010 11:23
Show Gist options
  • Save rubiii/563766 to your computer and use it in GitHub Desktop.
Save rubiii/563766 to your computer and use it in GitHub Desktop.
# extending Object by reopening the Object class:
class Object
def blank?
respond_to?(:empty?) ? empty? : !self
end
end
# it's not obvious, that Object was extended and you can't see
# who extended the Object class by inspecting its ancestors:
Object.ancestors # => [Object, Kernel]
# when using ruby 1.9.2 you're actually able to see exactly
# where a method was defined (which is very helpful):
Object.method(:blank?).source_location
# now let's extend Object by including a module (and pretend
# we are RSpec):
module RSpec
module CoreExt
module Object
def blank?
respond_to?(:empty?) ? empty? : !self
end
end
end
end
Object.send :include, RSpec::CoreExt::Object
# by inspecting Objects ancestors, you can see that someone
# "owning" the RSpec "namespace" extended Object:
Object.ancestors # => [Object, RSpec::CoreExt::Object, Kernel]
# extending classes (and this is not limited to core classes)
# using modules has essentially two benefits:
#
# 1. we can inspect the class hierarchy of any object and make a
# good guess who extended them
#
# 2. by leveraging ruby's class/module hierarchy, we can overwrite
# extensions by including our own module before anyone else
# includes something. this is not possible when reopening a
# class and adding methods to it(s metaclass) directly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment