[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

composition (Dragon "has a" Trait

Thufir Hawat

11/11/2007 3:31:00 AM

I want to put all of the current attr_accessor's
(:life, :strength, :charisma, :weapon) into class Traits so that each
Creature instance will have one Traits object to go along with that
class.

by themselves, Traits, Dragon and Class give no error messages from
ruby. From using the IRB it's clear that it's line 6 of the Dragon
class:

@traits.life = 1340


C:\code\creat3>
C:\code\creat3>
C:\code\creat3>creatures.rb
/Dragon.rb:6:in `initialize': undefined method `life=' for
nil:NilClass (NoMeth
odError)
from C:/code/creat3/creatures.rb:12:in `new'
from C:/code/creat3/creatures.rb:12
from C:/code/creat3/creatures.rb:10:in `times'
from C:/code/creat3/creatures.rb:10

C:\code\creat3>
C:\code\creat3>
C:\code\creat3>type creatures.rb
require 'ArrayOfCreatures'
require 'MakeCreature'
require 'Location'

include MakeCreature

NumOfCreatures=3
creatures = ArrayOfCreatures.instance

NumOfCreatures.times do |i|
# creatures[i]=MakeCreature.randomCreature
creatures[i]=Dragon.new
end

creatures.length.times do |i|
number = Kernel.rand(6)
creatures.oneElementToString(i)
print "factorial of\t"
print number
print "\tis\t"
print Math.factorial(number)
end

C:\code\creat3>
C:\code\creat3>
C:\code\creat3>type Creature.rb
require 'Math'
require 'Traits'

class Creature

Creature.extend Math
include Math


def initialize ()
@location = Room.new
@traits = Traits.new
end

def toString ()
print "class\t\t"
print self.class

@attributes.toString

print "\n"
end


end

C:\code\creat3>
C:\code\creat3>type Dragon.rb
require 'Creature'

class Dragon < Creature

def initialize ()
@traits.life = 1340
end


end

C:\code\creat3>
C:\code\creat3>



thanks,

Thufir


2 Answers

Phrogz

11/11/2007 3:41:00 AM

0

Thufir wrote:
> C:\code\creat3>type Creature.rb
> class Creature
....
> def initialize ()
> @location = Room.new
> @traits = Traits.new
> end
....
> end
....
> class Dragon < Creature
> def initialize ()
> @traits.life = 1340
> end
> end

It seems you think that the initialize of Creature gets called because
Dragon is a subclass of it. This is not the case. For example:

irb(main):001:0> class Foo
irb(main):002:1> def initialize
irb(main):003:2> p "Foo.initialize"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> Foo.new
"Foo.initialize"

irb(main):007:0> class Bar < Foo
irb(main):008:1> def initialize
irb(main):009:2> p "Bar.initialize"
irb(main):010:2> end
irb(main):011:1> end
=> nil
irb(main):012:0> Bar.new
"Bar.initialize"


If you want the initialize method from a superclass to be called, you
need to explicitly do so, and decide when to do it. For example:

irb(main):019:0> class Bar2 < Foo
irb(main):020:1> def initialize
irb(main):021:2> super # call this first
irb(main):022:2> p "Bar2.initialize"
irb(main):023:2> end
irb(main):024:1> end
=> nil
irb(main):025:0> Bar2.new
"Foo.initialize"
"Bar2.initialize"


Though it doesn't make a difference in my above simple example, note
that calling "super" without any parentheses automatically passes in
any arguments passed to the initialize function. This is convenient,
but can be a problem if your superclass's initialize method expects
different arguments than the subclass's.

Thufir Hawat

11/13/2007 6:03:00 AM

0

Oh, thanks for pointing out how to ensure that the initialize
(constructor) method is called.


-Thufir