2

How do I use Ruby to access the properties of an object containing an array of objects?

I have a variable that looks something like this:

@myvar = [#<MYOBJECT::MObject0x00000000000000="000", @id="1000", 
@status="Open", @color="Red">, #<MYOBJECT::MObject0x00000000000001="001", 
@id="1001", @status="Closed", @blue="450">]

I tried:

@myvar.each(|name| puts "Status: #{name.status}  Color: #{name.color}"

But it returns the full object instead of the property values.

1
  • In this case the problem is not in the code. The OP said he got return values instead of syntax errors. But you are free to decide which version is clearer. Commented Aug 1, 2013 at 3:33

4 Answers 4

4

When you call Array#each with a block, it returns the array itself. Perhaps you're looking for Array#map:

array_of_strings = @myvar.map { |name| "Status: #{name.status}  Color: #{name.color}" }
Sign up to request clarification or add additional context in comments.

Comments

3

According to the documentation, Array#each returns an array if you supply a block.

If you want an array of "properties", use Array#map. For example,

@myvar.map { |obj| obj.status }
#=> ["Open", "Closed", ...]

Map creates a new array and replaces each element in @myvar with the value 'returned' by the block. Note that this assumes you have a getter method for status and other attributes. If you don't, you can create them using attr_reader :status, ....

There is also a more concise version:

@myvar.map(&:status)
#=> ["Open", "Closed", ...]

(See The & Operator in Ruby.)

1 Comment

Technically, Array#each only returns the array when you supply a block, if you leave out the block, each will give you an Enumerator instead.
0

You can get instance variable by calling instance_variable_get("@name")

@myvar.each { |myObject| puts "Status: #{myObject.instance_variable_get("@status")}  Color: #{myObject.instance_variable_get("@color")}" }

Hope it helps.

Comments

0

For starters there is a syntax error in the way you are calling each with a paren "(" instead of with curly braces "{". Then there is no corresponding closing paren/brace at the end of the statement. The correct invocation should like -

@myvar.each {|name| puts "Status: #{name.status}  Color: #{name.color}"}

And this will work only if you have methods status and color defined in MyObject. If you don't have these methods defined then look at Mike Li's answer to directly access instance variables. This is of course violating OO encapsulation design principle.

Secondly, I noticed that MyObject with id 1001 does not have the color attribute, it has an attribute named blue with a value of 450.

In order to get a more precise answer to your question, it would help if you could paste in the class definition of MyObject and the exact error that you are getting.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.