ruby, a teeny bit at a time.

So I’ve learned Ruby and I am in love. And I just learned something that is going to make my life a whole lot easier and my scripts a lot less convoluted. Perhaps this was in one of the several books/tutorials I’ve read on the language, but I don’t remember it, or it was not presented in a way that seemed relevant to my applications.

My question was how do I get back to nameless, label-less objects based on their instance attributes? Here’s a silly example:

Here’s the definition of the Cat class:

class Cat
attr_reader :name, :byear

def initialize(name, byear)
@name = name
@byear = byear
end #def initialize
end #class Cat

My initial array—I’ll call it catdata—looked like this:
[["Be", 1996], ["Cu", 1996], ["Hal", "unknown"], ["Felix", 1919]]

I created an array of Cat objects:
cats = []

catdata.each do |e|
newcat = Cat.new(e[0], e[1])
cats.push(newcat)
end #catdata.each do

Now cats is an array of mysterious objects:
[#<Cat:0x7ff6d324>, #<Cat:0x7ff6d34c>, ...etc]

My Problem: Variable names are not assigned to the Cat objects when they are created. How do I access those Cat objects using their instance attributes? For instance, if I want to pull out all the cats born in 1996, what do I do?

I’d come up with a very ugly workaround (don’t ask), but this is much, much cleaner and I believe it can easily be defined as a method for the Cat class. (And if there is an even better/more direct way to do this, please share!)

_1996cats = cats.find_all do |cat|
cat.instance_variable_get(:@byear) == 1996
end

The result is an array with two elements: the objects for Be and Cu. Hooray!

Leave a Reply

Your email address will not be published. Required fields are marked *