# Included module and scope confusion

**URL:** <https://www.ruby-forum.com/t/included-module-and-scope-confusion/52085>\
**Category:** Ruby\
**Created:** [January 10, 2006, 8:12pm UTC](https://www.ruby-forum.com/t/included-module-and-scope-confusion/52085 "2006-01-10T20:12:53Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![hmmm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ce73a5/32.png) [@hmmm](https://www.ruby-forum.com/u/hmmm)\
**Post date:** [January 10, 2006, 8:12pm UTC](https://www.ruby-forum.com/t/included-module-and-scope-confusion/52085/1 "2006-01-10T20:12:53Z")

</div>

I am confused about modules and scope.

Here is a module:

module Crumbs  
MAX\_CRUMBS = 10

def self.included(mod)  
def cookies  
return @cookies == nil ? Hash.new : @cookies  
end  
end

def crumb\_new( controller, action, params )  
cstr = controller + “^” + action  
if params != nil && params.keys != nil  
params.keys.each {|p|  
if params[p] != nil  
cstr \<\< “^” \<\< p \<\< “^” \<\< params[p]  
end  
}  
end  
return cstr  
end

def crumb\_add( bite )  
cbs = @cookies  
puts cbs.class  
cbs = cbs[:rdf\_crumbs]  
if cbs == nil  
puts “crumb\_add::cbs is nil!”  
cbs =[bite]  
else  
puts “crumb\_add::cbs is OK!”  
cbs = cbs.split("|")  
#don’t add a redundant  
if cbs.last == bite  
return  
end  
# add to  
cbs \<\< bite  
# cap the cookie queue at 5 using fifo  
if cbs.length \> @@MAX\_CRUMBS  
cbs.delete\_at(0)  
end  
end  
crumbs\_set( cbs )  
end

def crumbs\_set( mouthful )  
cr = “”  
mouthful.each { |m|  
if cr == “”  
cr = m  
else  
cr \<\< “|” \<\< m  
end  
}  
puts cookies.class  
cookies[:rdf\_crumbs] = cr  
end

def get\_crumbs()  
crs = @cookies[“rdf\_crumbs”]  
if crs == nil  
return []  
else  
return crs.split("|")  
end  
end

# end

# Here is a unit test:

class Bread  
include Crumbs  
def initialize  
@cookies = Hash.new  
end  
end

class CrumbTest \< Test::Unit::TestCase

attr :bread

def setup  
@bread = Bread.new  
end

def test\_crumbs\_simple  
@params = Hash.new  
bite =bread.crumb\_new( “test1”, “test\_action”, @params )  
bread.crumb\_add(bite)  
puts bite  
bite =bread.crumb\_new( “test2”, “test\_action\_2”, @params )  
bread.crumb\_add(bite)  
puts bite  
bite =bread.crumb\_new( “test3”, “test\_action\_3”, @params )  
bread.crumb\_add(bite)  
puts bite  
assert bite == “test3^test\_action\_3”  
bites =bread.get\_crumbs()  
puts bites.class  
assert\_equal bites.length, 3  
end  
end

## Here is the output:

## test cookies! on Bread Hash crumb\_add::cbs is nil! sets Hash with test1^test\_action has 1 test1^test\_action Hash crumb\_add::cbs is nil! sets Hash with test2^test\_action\_2 has 1 test2^test\_action\_2 Hash crumb\_add::cbs is nil! sets Hash with test3^test\_action\_3 has 1 test3^test\_action\_3

## And:

## Test::Unit::AssertionFailedError: \<1\> expected but was \<3\>. test/unit/crumbs\_test.rb:62:in `test\_crumbs\_simple’

I have tried different ways, but can’t get the Correct Way to have a  
module  
insert a variable into the Class that includes it. In this case it  
should  
inject a @cookies hash, but in tests @cookies always gets reset to  
Hash.new…

Excuse the inconsistencies in the code (towards @cookies) b/c I can’t  
seem  
to figure out the proper way.

So how do you add instance vars to a class from a module and how to  
reference that attribute? Or is this not the Right Ruby Way?

I have a lot of confusion about modules… suppose its my java funk 😕

Please point me to any more docs on modules besides the ruby-lang  
snippet.

-netcam

---

<div class="post-metadata">

**Author:** ![hmmm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ce73a5/32.png) [@hmmm](https://www.ruby-forum.com/u/hmmm)\
**Post date:** [January 10, 2006, 8:28pm UTC](https://www.ruby-forum.com/t/included-module-and-scope-confusion/52085/2 "2006-01-10T20:28:07Z")

</div>

Before I was mixing (include) Crumbs on the unit test class and I think  
there was a name collision with the rails test\_helper.rb file and  
@cookies  
hence it got me all confused.

Ok here is what I did, and it seems simple. But a better way it seems  
would  
to do it transparently to the subclass on the module, so if anyone knows  
how, divulge. I don’t want to have to declare the attr\_reader :cookies  
on  
the Class.

class Bread  
include Crumbs

attr\_reader :cookies

def initialize  
@cookies = Hash.new  
end  
end

module Crumbs

# def self.included(mod)

# puts “test cookies! on #{mod}”

# def mod.cookies

# if @cookies == nil

# @cookies = Hash.new

# end

# return @cookies

# end

# end

#----------------------------------------  
#--------------begin/ cookie crumbs mixin  
#----------------------------------------  
MAX\_CRUMBS = 10

def crumbs\_clear  
if @cookies != nil and @cookies[“rdf\_crumbs”] != nil  
@cookies.delete “rdf\_crumbs”  
end  
end

def crumb\_new( controller, action, params )  
cstr = controller + “^” + action  
if params != nil && params.keys != nil  
params.keys.each {|p|  
if params[p] != nil  
cstr \<\< “^” \<\< p \<\< “^” \<\< params[p]  
end  
}  
end  
return cstr  
end

def crumb\_add( bite )  
cbs = @cookies  
puts cbs.class  
cbs = cbs[“rdf\_crumbs”]  
if cbs == nil  
puts “crumb\_add::cbs is nil!”  
cbs =[bite]  
else  
puts “crumb\_add::cbs is OK!”  
cbs = cbs.split("|")  
#don’t add a redundant  
if cbs.last == bite  
return  
end  
# add to  
cbs \<\< bite  
# cap the cookie queue at 5 using fifo  
if cbs.length \> MAX\_CRUMBS  
cbs.delete\_at(0)  
end  
end

```
crumbs_set( cbs )

```

end

def crumbs\_set( mouthful )  
cr = “”  
mouthful.each { |m|  
if cr == “”  
cr = m  
else  
cr \<\< “|” \<\< m  
end  
}  
puts “sets #{@cookies.class} with #{cr}”  
if @cookies == nil  
@cookies = Hash.new  
end  
@cookies[“rdf\_crumbs”]=cr  
puts “has #{@cookies.keys.length}”  
end

def crumb\_del( bite )  
crs = cookies[:rdf\_crumbs]  
if crs != nil  
crs = crumbs.split("|")  
c2 =""  
crs.each { |c|  
if crs[c] != bite  
if c2 == “”  
c2 = c  
else  
c2 \<\< “|” \<\< c  
end  
end  
}  
cookies[:rdf\_crumbs] =c2  
end  
end

def get\_crumbs()  
crs = @cookies[“rdf\_crumbs”]  
if crs == nil  
return []  
else  
return crs.split("|")  
end  
end

#----------------------------------------  
#--------------end/ cookie crumbs mixin  
#----------------------------------------  
end

---

<div class="post-metadata">

**Author:** ![hmmm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ce73a5/32.png) [@hmmm](https://www.ruby-forum.com/u/hmmm)\
**Post date:** [January 10, 2006, 10:47pm UTC](https://www.ruby-forum.com/t/included-module-and-scope-confusion/52085/3 "2006-01-10T22:47:27Z")

</div>

Ok here is the final version…

# Unit Test:

class Bread  
include Crumbs  
def cookies  
@cookies ||= Hash.new  
end  
def initialize  
@cookies = Hash.new  
end  
end

class CrumbTest \< Test::Unit::TestCase

attr :bread

def setup  
@bread = Bread.new  
end

# Simple add/delete/clear tests

def test\_crumbs\_simples  
@params = Hash.new  
bite =bread.crumb\_new( “test1”, “test\_action”, @params )  
bread.crumb\_add(bite)  
bite =bread.crumb\_new( “test2”, “test\_action\_2”, @params )  
bread.crumb\_add(bite)  
bite =bread.crumb\_new( “test3”, “test\_action\_3”, @params )  
bread.crumb\_add(bite)  
assert bite == “test3^test\_action\_3”  
bites =bread.get\_crumbs()  
assert\_equal bites.length, 3  
bread.crumbs\_clear()  
bites =bread.get\_crumbs()  
assert\_equal bites.length, 0  
bite =bread.crumb\_new( “test1”, “test\_action”, @params )  
bread.crumb\_add(bite)  
bread.crumb\_del(bite)  
bites =bread.get\_crumbs()  
assert\_equal bites.length, 0  
end

def test\_crumbs\_params  
bite =bread.crumb\_new( “test1”, “test\_action”,  
{“filter”=\>“s`divx:divx”})  
bread.crumb\_add(bite)  
bites =bread.get\_crumbs()  
assert\_equal bites[0], bite  
end  
end

# And the crumbs module:

module Crumbs  
#----------------------------------------  
#--------------begin/ cookie crumbs mixin  
#----------------------------------------  
MAX\_CRUMBS = 10

public  
def crumbs\_clear  
if cookies != nil and cookies[:rdf\_crumbs] != nil  
cookies.delete :rdf\_crumbs  
end  
end

def crumb\_new( controller, action, params )  
cstr = controller + “^” + action  
if params != nil && params.keys != nil  
params.keys.each {|p|  
if params[p] != nil  
cstr \<\< “^” \<\< p \<\< “^” \<\< params[p]  
end  
}  
end  
return cstr  
end

def crumb\_add( bite )  
cbs = cookies[:rdf\_crumbs]  
if (cbs == nil or cbs == “”) or (cbs.instance\_of? Array and  
cbs.length==0)  
cbs =[bite]  
else  
cbs = cbs.split("|")  
#don’t add a redundant  
if cbs.last == bite  
return  
end  
# add to  
cbs \<\< bite  
# cap the cookie queue at 5 using fifo  
if cbs.length \> MAX\_CRUMBS  
cbs.delete\_at(0)  
end  
end

```
crumbs_set( cbs )

```

end

def crumbs\_set( mouthful )  
cr = “”  
mouthful.each { |m|  
if cr == “”  
cr = m  
else  
cr \<\< “|” \<\< m  
end  
}  
cookies[:rdf\_crumbs]=cr  
end

def crumb\_del( bite )  
crs = cookies[:rdf\_crumbs]  
if crs != nil  
crs = crs.split("|")  
c2 =""  
crs.each { |c|  
if c != bite  
if c2 == “”  
c2 = c  
else  
c2 \<\< “|” \<\< c  
end  
end  
}  
cookies[:rdf\_crumbs] =c2  
end  
end

def get\_crumbs()  
crs = cookies[:rdf\_crumbs]  
if crs == nil  
return []  
else  
return crs.split("|")  
end  
end

#----------------------------------------  
#--------------end/ cookie crumbs mixin  
#----------------------------------------  
end

---

<div class="post-metadata">

**Author:** ![hmmm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ce73a5/32.png) [@hmmm](https://www.ruby-forum.com/u/hmmm)\
**Post date:** [January 11, 2006, 10:55am UTC](https://www.ruby-forum.com/t/included-module-and-scope-confusion/52085/4 "2006-01-11T10:55:34Z")

</div>

hmmm wrote:

> I have tried different ways, but can’t get the Correct Way to have a  
> module insert a variable into the Class that includes it. In this  
> case it should inject a @cookies hash, but in tests @cookies always  
> gets reset to Hash.new…

Of course because you assign it in initialize.

Two options:

1 Lazy init: You need to define cookies differently and access it always  
through the getter method (attachment ex1.rb)

2 Init during constructor: you need to define #initialize in the module  
and either leave initialize out of Bread or use super (attachment  
ex2.rb)

Module#included is completely wrong here as you do not want to do  
anything  
to the class that uses the mod.

> Excuse the inconsistencies in the code (towards @cookies) b/c I can’t  
> seem to figure out the proper way.
> 
> So how do you add instance vars to a class from a module and how to  
> reference that attribute? Or is this not the Right Ruby Way?
> 
> I have a lot of confusion about modules… suppose its my java funk 😕

Apparently. 🙂

> Please point me to any more docs on modules besides the ruby-lang  
> snippet.

HTH

Kind regards

```
robert
```
