composition (Dragon "has a" Trait)

T

Thufir

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=MakeCreature.randomCreature
creatures=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
 
P

Phrogz

Thufir said:
C:\code\creat3>type Creature.rb
class Creature ....
def initialize ()
@location = Room.new
@traits = Traits.new
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.
 
T

Thufir

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


-Thufir
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top