# Module scope not clear to me

**URL:** <https://www.ruby-forum.com/t/module-scope-not-clear-to-me/150132>\
**Category:** Ruby\
**Created:** [October 4, 2008, 8:14am UTC](https://www.ruby-forum.com/t/module-scope-not-clear-to-me/150132 "2008-10-04T08:14:34Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [October 4, 2008, 8:14am UTC](https://www.ruby-forum.com/t/module-scope-not-clear-to-me/150132/1 "2008-10-04T08:14:34Z")

</div>

I had a program which inherits from a superclass. It also has  
common/convenience methods in a module.

`
 require 'common'
 include 'Common'
 class Prog < Application
    f = Obj.new
    g = Foo.new
    #... etc ...
`

Some convenience methods rely on a variable being set in the superclass.  
(I know that does not sound good but it shields this detail from  
individual programs.)

Then i refactored … moved a lot of functionality out from the program  
to objects it was creating. I would guess that these objects should  
_not_ be able to call the module methods. Suprisingly, they were.

The problem came up that the variable was obviously not set when called  
by these objects, (since the class of the module was now the object’s  
class not the program’s class.)

So my basic question is: if a program includes a module, can all its  
composed objects also call on the module.

What are the scope rules?

Any do’s and don’ts/insights/suggestions are welcome.

---

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [October 4, 2008, 10:12am UTC](https://www.ruby-forum.com/t/module-scope-not-clear-to-me/150132/2 "2008-10-04T10:12:26Z")

</div>

Nit K. wrote:

> I had a program which inherits from a superclass. It also has  
> common/convenience methods in a module.
> 
> `
> require 'common'
> include 'Common'
> class Prog < Application
> f = Obj.new
> g = Foo.new
> #... etc ...
> `
> 
> Some convenience methods rely on a variable being set in the superclass.  
> (I know that does not sound good but it shields this detail from  
> individual programs.)
> 
> Then i refactored … moved a lot of functionality out from the program  
> to objects it was creating. I would guess that these objects should  
> _not_ be able to call the module methods. Suprisingly, they were.
> 
> The problem came up that the variable was obviously not set when called  
> by these objects, (since the class of the module was now the object’s  
> class not the program’s class.)
> 
> So my basic question is: if a program includes a module, can all its  
> composed objects also call on the module.

Depends on where the module is included. If its included at the top  
level (outside of another class/module) then it’s mixed into the Object  
class from which all other classes ultimately derive , so method lookup  
on any object will always find it.

```
module M
  def foo; puts "module foo" end
end

class C; end
# method name resolution chain before include
p C.ancestors #=> [C, Object, Kernel]

include M # including at top level has M as the

p C.ancestors #=> [C, Object, M, Kernel]

C.new.foo #=> module foo

# heck you can even call it on "M", "C" since they are also objects
M.foo #=> module foo
C.foo #=> module foo.

```

Once you include a module at the _top level_ you are creating a set of  
methods accessible from anywhere.

–Cheers  
–Ragav

---

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [October 4, 2008, 11:23am UTC](https://www.ruby-forum.com/t/module-scope-not-clear-to-me/150132/3 "2008-10-04T11:23:30Z")

</div>

Ragav S. wrote:

> > `
> > require 'common'
> > include 'Common'
> > class Prog < Application
> > f = Obj.new
> > g = Foo.new
> > #... etc ...
> > `
> 
> Depends on where the module is included. If its included at the top  
> level (outside of another class/module) then it’s mixed into the Object  
> class from which all other classes ultimately derive , so method lookup  
> on any object will always find it.  
> –Cheers  
> –Ragav

Wow ! That said, earlier in the case i gave above is it at the top  
level?

Because my situation was like this (before refactoring). There were 2  
classes in my file, and the first did NOT find it. It had to use a  
reference of the second class to call the module methods. Let me  
explain:

==== common.rb contains:  
def printme  
end

==== prog.rb

require ‘common’  
include ‘Common’

class Datasource  
# saves reference to Prog in constructor  
def initialize (app)  
@main = app  
end

```
  printme # this failed.
  @main.printme # this works
end

```

class Prog \< Application  
new Datasource(self)  
printme # works  
end

if **FILE** == $0  
p = new Prog…  
p.run …  
end

== end of file

Here, class Prog was able to refer to all Module methods, but class  
datasource could not and i had to pass a ref of Prog, so it could.

---

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [October 4, 2008, 11:26am UTC](https://www.ruby-forum.com/t/module-scope-not-clear-to-me/150132/4 "2008-10-04T11:26:02Z")

</div>

> ```
> p = new Prog...
> 
> ```

Sorry that should read Prog.new (old java habits still lingering) , the  
above is not the real source code, just a represntative sample.

---

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [October 4, 2008, 1:34pm UTC](https://www.ruby-forum.com/t/module-scope-not-clear-to-me/150132/5 "2008-10-04T13:34:45Z")

</div>

Hi –

On Sat, 4 Oct 2008, Nit K. wrote:

> > >
> 
> Because my situation was like this (before refactoring). There were 2  
> require ‘common’  
> include ‘Common’

That’s an error: you include modules, not strings. But there’s no  
Common module anyway, so it’s an error either way.

> class Datasource  
> # saves reference to Prog in constructor  
> def initialize (app)  
> @main = app  
> end
> 
> ```
> printme # this failed.
> @main.printme # this works
> 
> ```

If you fix the errors I pointed out above, both of these call printme.  
@main is nil at this point (and keep in mind that this @main has  
nothing to do with the @main in initialize).

> end
> 
> class Prog \< Application  
> new Datasource(self)

No such method.

> ```
> printme # works
> 
> ```
> 
> end

This is so full of errors that it’s impossible to know what your real  
problem was. Can you post some actual code that illustrates the  
problem? It’s not only easier for people trying to help you but  
ultimately much more relevant for you, if you present your actual  
problem and not a set of problems that only exist because you’ve  
introduced them into your post.

David

---

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [October 4, 2008, 2:30pm UTC](https://www.ruby-forum.com/t/module-scope-not-clear-to-me/150132/6 "2008-10-04T14:30:03Z")

</div>

David A. Black wrote:

> Hi –
> 
> On Sat, 4 Oct 2008, Nit K. wrote:
> 
> This is so full of errors that it’s impossible to know what your real  
> problem was. Can you post some actual code that illustrates the  
> problem? It’s not only easier for people trying to help you but  
> ultimately much more relevant for you, if you present your actual  
> problem and not a set of problems that only exist because you’ve  
> introduced them into your post.
> 
> David  
> My sincere apologies. In future I will make a running sample before  
> posting.

I did make a sample, and found that the problem was the _variable_ that  
was in the scope of one class, not the other. So my question is  
basically wrong - sorry again for wasting your time.
