alternate to case; generating a list of sub-classes

T

Thufir

The below uses pseudo-random number generation to populate an array
with various monsters, all inherit from Creature. Can a list of
classes which inherit from Creature be generated automagically? There
must be a better technique to fill the array then the case
statement...


C:\code>
C:\code>
C:\code>type Driver.rb
require 'ArrayOfCreatures'

require 'Creature'
require 'AssistantViceTentacleAndOmbudsman'
require 'Dragon'
require 'DwarvenAngel'
require 'TeethDeer'



puts "\nquantity of creatures:"
numOfCreatures = gets.chomp.to_i


someCreatures = ArrayOfCreatures.new


0.upto(numOfCreatures) do |i|

creatureType = Kernel.rand(4)

case creatureType
when 0
someCreatures=AssistantViceTentacleAndOmbudsman.new
when 1
someCreatures=Dragon.new
when 2
someCreatures=DwarvenAngel.new
when 3
someCreatures=TeethDeer.new
end
end

someCreatures.toString


C:\code>
C:\code>


thanks,

Thufir
 
A

Alex Fenton

Thufir said:
The below uses pseudo-random number generation to populate an array
with various monsters, all inherit from Creature. Can a list of
classes which inherit from Creature be generated automagically?

Perhaps:

class Creature
@creature_classes = []
# hook to note when a class inherits
def self.inherited(klass)
@creature_classes << klass
end

# generate a random creature from among known subclasses
def self.random_creature
@creature_classes[ rand(@creature_classes.length) ].new
end
end

hth
alex
 
D

David A. Black

Hi --

The below uses pseudo-random number generation to populate an array
with various monsters, all inherit from Creature. Can a list of
classes which inherit from Creature be generated automagically? There
must be a better technique to fill the array then the case
statement...


C:\code>
C:\code>
C:\code>type Driver.rb
require 'ArrayOfCreatures'

require 'Creature'
require 'AssistantViceTentacleAndOmbudsman'
require 'Dragon'
require 'DwarvenAngel'
require 'TeethDeer'



puts "\nquantity of creatures:"
numOfCreatures = gets.chomp.to_i


someCreatures = ArrayOfCreatures.new


0.upto(numOfCreatures) do |i|

creatureType = Kernel.rand(4)

case creatureType
when 0
someCreatures=AssistantViceTentacleAndOmbudsman.new
when 1
someCreatures=Dragon.new
when 2
someCreatures=DwarvenAngel.new
when 3
someCreatures=TeethDeer.new
end
end

someCreatures.toString


Here's one possibility (untested):

creatures = ArrayOfCreatures.new
creature_classes = [AssistantViceTentacleAndOmbudsman, Dragon,
DwarvenAngel, TeethDeer]

puts "\nquantity of creatures:"
num_of_creatures = gets.to_i

num_of_creatures.times do |i|
creatures = creature_classes[rand(4)].new
end


David

--
Upcoming training by David A. Black/Ruby Power and Light, LLC:
* Advancing With Rails, Edison, NJ, November 6-9
* Advancing With Rails, Berlin, Germany, November 19-22
* Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See http://www.rubypal.com for details!
 
A

ara.t.howard

The below uses pseudo-random number generation to populate an array
with various monsters, all inherit from Creature. Can a list of
classes which inherit from Creature be generated automagically? There
must be a better technique to fill the array then the case
statement...

cfp: ~> cat a.rb

class Creature
Children = []

def self.inherited other
super
ensure
Children << other
end
end

Creature::List.sort_by{ rand }


a @ http://codeforpeople.com/
 
T

Thufir

Thufir said:
The below uses pseudo-random number generation to populate an array
with various monsters, all inherit from Creature. Can a list of
classes which inherit from Creature be generated automagically?

Perhaps:

class Creature
@creature_classes = []
# hook to note when a class inherits
def self.inherited(klass)
@creature_classes << klass
end
[...]

Aha, I've been trying to figure out what a "hook" meant! :)


thanks,

Thufir
 
P

Phrogz

cfp: ~> cat a.rb

class Creature
Children = []
[snip]
end

As an off-topic aside, I really like what you've done here. Normally I
do things like this:

class Foo
@all = []
class << self
attr_reader :all
end
def initialize
self.class.all << self
end
end

....but I've now seen the light how a constant scoped to the class can
make life far simpler.

class Foo
ALL = []
def initialize
ALL << self
end
end

There's even some interesting benefits to the scoping, like:

# By inheriting the superclass's initialize,
# Bar1 instances get put into Foo::ALL
class Bar1 < Foo; end

# But I can totally branch on my own without worrying about
# any class variable sort of nonsense
class Bar2 < Foo
ALL = [] # separate from Foo::ALL
def initialize
ALL << self
end
end

Thanks for that, Ara!
 
J

Joel VanderWerf

Phrogz said:
class Foo
ALL = []
def initialize
ALL << self
end
end

There's even some interesting benefits to the scoping, like:

# By inheriting the superclass's initialize,
# Bar1 instances get put into Foo::ALL
class Bar1 < Foo; end

# But I can totally branch on my own without worrying about
# any class variable sort of nonsense
class Bar2 < Foo
ALL = [] # separate from Foo::ALL
def initialize
ALL << self
end
end

Thanks for that, Ara!

Careful though, constant scoping is not dynamic:

class Foo
def self.show_all
p ALL
end
end

3.times {Foo.new}
Foo.show_all # [#<Foo:0x2ae5e8c>, #<Foo:0x2ae5e78>, #<Foo:0x2ae5e64>]

3.times {Bar2.new}
Bar2.show_all # [#<Foo:0x2ae5e8c>, #<Foo:0x2ae5e78>, #<Foo:0x2ae5e64>]


Of course, you can get dynamic scoping, it's just easy to forget:

class Foo
def self.show_all
p self::ALL
end
end
 
R

Robert Klemme

2007/11/8 said:
The below uses pseudo-random number generation to populate an array
with various monsters, all inherit from Creature. Can a list of
classes which inherit from Creature be generated automagically? There
must be a better technique to fill the array then the case
statement...

I usually do this when I want to also recursively track subclasses:

module Hierarchy
def inherited(cl)
superclass.instance_eval { inherited cl }
(@children ||= []) << cl
cl.extend Hierarchy
end

attr_reader :children
end

class Foo
extend Hierarchy
end

class Bar < Foo
end

class Dice < Bar
end

p Bar.children
p Foo.children

Cheers

robert
 
S

Sebastian Hungerecker

David said:
creatures = ArrayOfCreatures.new
[...]
num_of_creatures.times do |i|
creatures = creature_classes[rand(4)].new
end


Assuming that ArrayOfCreatures.new works like Array.new this can be simplified
to:
creatures = ArrayOfCreatures.new(num_of_creatures) do |i|
creature_classes[rand(4)].new
end
 
T

Thufir

On Nov 8, 10:13 am, Sebastian Hungerecker
[...]
Assuming that ArrayOfCreatures.new works like Array.new this can be simplified
to:
creatures = ArrayOfCreatures.new(num_of_creatures) do |i|
creature_classes[rand(4)].new
end

It took me a few reads to appreciate, but I like that alot :)


-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,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top