[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

simple ruby language question

MichaelEconomy

3/19/2006 7:11:00 PM

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

4 Answers

Scott

3/19/2006 8:43:00 PM

0

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

Marcin Mielzynski

3/19/2006 9:59:00 PM

0

MichaelEconomy@gmail.com wrote:
> 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
>

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

Marcin Mielzynski

3/19/2006 10:04:00 PM

0

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

Robert Klemme

3/20/2006 8:45:00 AM

0

Marcin MielżyÅ?ski wrote:
> 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

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