# Simple ruby language question

**URL:** <https://www.ruby-forum.com/t/simple-ruby-language-question/83976>\
**Category:** Ruby\
**Created:** [March 19, 2006, 8:13pm UTC](https://www.ruby-forum.com/t/simple-ruby-language-question/83976 "2006-03-19T20:13:59Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 19, 2006, 8:13pm UTC](https://www.ruby-forum.com/t/simple-ruby-language-question/83976/1 "2006-03-19T20:13:59Z")

</div>

ok, i’ve got some module and it has some instance variables i want to  
be set by the classes extending the module, and aparently i’m not doing  
this correctly:

module A  
def test  
raise ‘ARG’ if !@blah  
@blah  
end  
end

class B  
include A  
extend A  
@blah = ‘YES!’  
end

irb(main):025:0\> b = B.new  
=\> #\<B:0x136376c\>  
irb(main):026:0\> b.test  
RuntimeError: ARG  
from (irb):9:in `test’  
from (irb):26

can anyone tell me what the syntax should be? how do i set @blah in the  
B class so that its available to the test method

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 19, 2006, 9:43pm UTC](https://www.ruby-forum.com/t/simple-ruby-language-question/83976/2 "2006-03-19T21:43:54Z")

</div>

In class B, you are attepmting to use an instance variable as if it  
were a class variable. To set @blah to a value when its instantiated,  
you’ll need to stick that line in the constructor:

class B  
include A  
extend A

def initialize  
@blah = ‘YES!’  
end  
end

Also, you dont need to both include and extend A inside B. Use extend  
when you want to use the modules methods as class methods:

module X  
def classy  
puts “Yup, I’m classy”  
end  
end

class Y  
extend X  
end

Y.classy  
=\> Yup, I’m classy

You can also extend an instance of an object:

s = “Holy shniekes”  
s.extend(X)  
s.classy  
=\> Yup, I’m classy

Use include when you want to “mix-in” the modules methods with the  
instance methods defined in the class:

module X  
def classy  
puts “Yup, I’m classy”  
end  
end

class Y  
include X  
end

Y.new.classy  
=\> Yup, I’m classy

Hope that helps 🙂

- Scott

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 19, 2006, 8:39pm UTC](https://www.ruby-forum.com/t/simple-ruby-language-question/83976/3 "2006-03-19T20:39:04Z")

</div>

Hi –

On Mon, 20 Mar 2006, removed\_email\_address@domain.invalid wrote:

> end  
> =\> #\<B:0x136376c\>  
> irb(main):026:0\> b.test  
> RuntimeError: ARG  
> from (irb):9:in `test’  
> from (irb):26
> 
> can anyone tell me what the syntax should be? how do i set @blah in the  
> B class so that its available to the test method

When using instance variables, you have to match each one precisely to  
the object whose instance variable it is. The @blah in @blah = ‘YES!’  
belongs to the class object B. The @blah inside test belongs (or will  
belong, upon execution) to whatever object is calling “test”. Unless  
that object is the class object B, its @blah will be different (even  
if it’s an instance of B).

So if you want them to match up, you have to call test on the class  
object B:

B.test

That will run “test” with B as the receiver, so you’ll see B’s  
instance variable @blah. (By the way, it’s a good idea not to name  
your test methods “test”, because there’s already a method with that  
name in Kernel, so sometimes you’ll get behavior you don’t expect.  
That’s not the issue here, though.)

David

–  
David A. Black (removed\_email\_address@domain.invalid)  
Ruby Power and Light, LLC ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))

“Ruby for Rails” chapters now available  
from Manning Early Access Program! [Ruby for Rails](http://www.manning.com/books/black)

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 19, 2006, 11:08pm UTC](https://www.ruby-forum.com/t/simple-ruby-language-question/83976/4 "2006-03-19T23:08:56Z")

</div>

Marcin MielÅ¼yÅ?ski wrote:

It can be easily seen who is the default receiver (class object or  
instance object) by doing this:

class A  
p self

```
 def initialize
     p self
 end

```

end

A.new

lopex

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 19, 2006, 11:03pm UTC](https://www.ruby-forum.com/t/simple-ruby-language-question/83976/5 "2006-03-19T23:03:59Z")

</div>

removed\_email\_address@domain.invalid wrote:

> end  
> =\> #\<B:0x136376c\>  
> irb(main):026:0\> b.test  
> RuntimeError: ARG  
> from (irb):9:in `test’  
> from (irb):26
> 
> can anyone tell me what the syntax should be? how do i set @blah in the  
> B class so that its available to the test method

Try this one:

module A  
def test  
raise ‘ARG’ if !@blah  
@blah  
end  
end

class B  
include A

def initialize  
@blah = ‘YES!’  
end  
end

b = B.new  
p b.test

Module#include will make module methods to become instance ones.  
Object#extend adds methods to an instance (to the class B in this case,  
you could say then B.test)

consider also:

class A  
@a=4  
end

p A.class\_eval{@a}  
=\> 4

which means that @a is an instance variable of class object, not an  
instance variable of class instance.

lopex

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 20, 2006, 9:54am UTC](https://www.ruby-forum.com/t/simple-ruby-language-question/83976/6 "2006-03-20T09:54:37Z")

</div>

Marcin MielÅ¼yÅ?ski wrote:

> def initialize  
> @blah = ‘YES!’  
> end  
> end
> 
> b = B.new  
> p b.test

You can even automate this with proper use of initializers:

module A  
def initialize(\*a,&b)  
super  
@blah = “set”  
end

def test  
raise ‘ARG’ if !@blah  
@blah  
end  
end

class B  
include A  
end

class C  
include A

def initialize(x)  
super()  
@another\_member = x  
end  
end

> > B.new.test  
> > =\> “set”
> 
> > C.new(1).test  
> > =\> “set”

> Module#include will make module methods to become instance ones.  
> Object#extend adds methods to an instance (to the class B in this case,  
> you could say then B.test)

Adding to that, usually the OP should decide whether to do one or  
another.

Kind regards

```
robert
```
