Created
September 3, 2010 11:23
-
-
Save rubiii/563766 to your computer and use it in GitHub Desktop.
This file contains 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
# 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