Petr Skocik
Petr Skocik

Reputation: 60185

Include or Extend When in the Main Scope

All over the Internet, I see people using "include" to bring new functionality to the main scope.

Most recenty, I saw this in an SO answer:

require 'fileutils' #I know, no underscore is not ruby-like
include FileUtils
# Gives you access (without prepending by 'FileUtils.') to
cd(dir, options)
cd(dir, options) {|dir| .... }
pwd()

Extend works too, but from my understanding, ONLY extend should work. I don't even know why the main object has the include functionality.

Inside the main scope:

self.class == Object  #true
Object.new.include    #NoMethodError: undefined method `include' for #<Object:0x000000022c66c0>

An I mean logically, since self.is_a?(Module) == false when inside the main scope, main shouldn't even have the include functionality, since include is used to add methods to child instances and main isn't a class or a module so there are no child instances to speak of.

My question is, why does include work in the main scope, what was the design decision that led to making it work there, and lastly, shouldn't we prefer "extend" in that case so as to not make the "extend/include" functionality even more confusing than it already may be thanks to people often using ruby hooks to invoke the other when one is called.

Upvotes: 1

Views: 57

Answers (1)

J&#246;rg W Mittag
J&#246;rg W Mittag

Reputation: 369633

The main scope is "special". Instance methods defined at the main scope become private instance methods of Object, constants become constants of Object, and include includes into Object. There's probably other things I'm missing. (E.g. presumably, prepend prepends to Object, I never thought about it until now.)

Upvotes: 3

Related Questions