Reputation: 137
(working in Ruby) First off, I apologize in advance. I'm not a programmer by training, I've simply come to it by dint of convenience and a changing world. What I needed to do involved programming, and I got tired of waiting around for others to do my programming for me. As such, I've missed some basic concepts along the way, and when I ask these questions I sometimes make a fool of myself by consequence.
Let's say I want to define a species/job relationship in classes. I want to define a superclass "BlackAnt" and have subclasses "Worker" "Fighter" and "Queen"
To me, intuitively, this looks something like this:
class BlackAnt
@legs = 6
end
class Worker < BlackAnt
@jaws = 'small'
end
but if I then try
ant1 = Worker.new
puts ant1.legs
I get an error. If I amend class BlackAnt to:
class BlackAnt
attr_accessor :legs
@legs = 6
end
ant1.legs returns 'nil'
I've tried the method outlined here: http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/
and this allows Worker.legs to return '6', but... alas:
ant1 = Worker.new
Worker.legs => '6'
ant1.legs => 'nil'
At a guess, the values of those parent variables are not being initialized each time a new child is spawned.
I feel I'm being silly about this somehow, and the reply is no doubt going to make me curse the day I discovered caffeine-driven all-nighters. What I need to do is arrange things so that I can create objects like so:
ant1 = Worker.new
ant2 = Queen.new
ant3 = Fighter.new
and have them each acquire the appropriate quantity of legs, along with whatever special characteristics were assigned in the child class. The worker/queen/fighter classifications will be bound by namespaces such that the actual calls will be:
ant1 = AntBlack::Worker.new
ant2 = AntRed::Worker.new
ant3 = AntRed::Queen.new
etc.
I'd like to then be able to check the quantity of legs of an individual ant using:
ant1.legs #=> 6
I may be going around my elbow to get to my thumb. If so, feel free to offer alternate suggestions for ways to achieve the same result, I will greatly appreciate the insights.
///updated re:response///
class AntRed
attr_accessor :legs
def initialize
@legs = 6
end
end
class Worker < AntRed
@strength = 1
end
result:
irb(main):009:0> ant1 = Worker.new
#=> #<Worker:0x87616ac @strength=1>
irb(main):010:0> ant1.legs
#=> nil
Upvotes: 3
Views: 5155
Reputation: 26
you mean you want a class's instance varieble which has been initialed!
so you can do it like this:
class BlackAnt
attr_accessor :legs
@legs = 6
def initialize
@legs = self.class.instance_variable_get(:@legs)
end
end
newObj = BlackAnt.new
newObj.legs
Upvotes: 0
Reputation: 3734
At a guess, the values of those parent variables are not being initialized each time a new child is spawned.
In Ruby instance variables belong to a single object. Look at point 7) in my answer starting
To address your "If true that they are variables"
in Why are symbols in Ruby not thought of as a type of variable?
I don't understand why you get irb(main):010:0> ant1.legs #=> nil
. For me it works (at least as script).
class AntRed
attr_accessor :legs
def initialize
@legs = 6
end
end
class Worker < AntRed
end
ant1 = Worker.new
print 'ant1.legs : '; puts ant1.legs
Execution :
$ ruby -w test.rb
ant1.legs : 6
Upvotes: 0
Reputation: 766
Define your BlackAnt class as follows:
class BlackAnt
attr_accessor :legs
def initialize
@legs = 6
end
end
And your Worker class as follows:
class Worker < BlackAnt
attr_accessor :strength
def initialize
super
@strength = 1
end
end
The way you currently define the BlackAnt class, you are storing legs as a class level instance variable.
Upvotes: 5