# Arrays with records as objects

**URL:** <https://rubytalk.org/t/arrays-with-records-as-objects/66736>\
**Category:** ruby-talk\
**Created:** [22 November 2012 12:52 UTC](https://rubytalk.org/t/arrays-with-records-as-objects/66736 "2012-11-22T12:52:39Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [22 November 2012 12:52 UTC](https://rubytalk.org/t/arrays-with-records-as-objects/66736/1 "2012-11-22T12:52:39Z")

</div>

I am completely new to Ruby.  
I have been reading through the tutorials and trying to build an example  
set.

One example I saw was a basic todo list. I have then taken that example  
and tried to modify it.

What I want is a file with two fields, action no, and text.  
That file is read, and from each entry in the file, an 'item' object is  
created that contains a record structure of status, action no and text.

That 'item' object is then loaded into a 'todo list' and the list  
displayed on screen for the user to mark the completed actions.

I have then two objects - the 'todo list' and the 'todo item'. The item  
has an initializer that takes the delimited file line (format action  
no\<\<\>\>text) and splits that line into a structure that also has a  
status.

My todo list has a list array. I want to load the list array with the  
item objects and am using the \<\< operator as:

@list \<\< item\_rec

This seems to work ok, and my array goes from 0 length to 1. But, I had  
hoped then to access the record fields via 'list', ie:  
list[0].action  
but when I try to access the 'list[n].action' I seem to have nil in the  
field(s),although looking at 'list' in total seems to show the data.  
List is ([#\<TodoItem:0x8379f30 @item\_rec=#\<OpenStruct done=false,  
action="1", name="hgafafgafgagaf"\>\>])

Is it because I have an array of 'objects' - ie 'list' now contains a  
single element of class 'TodoItem'? If so, how do I access the  
'item\_rec' sub object of 'list'?

Does any of that make sense?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [22 November 2012 13:59 UTC](https://rubytalk.org/t/arrays-with-records-as-objects/66736/2 "2012-11-22T13:59:36Z")

</div>

> My todo list has a list array. I want to load the list array with the  
> item objects and am using the \<\< operator as:
> 
> @list \<\< item\_rec
> 
> This seems to work ok, and my array goes from 0 length to 1. But, I had  
> hoped then to access the record fields via 'list', ie:  
> list[0].action  
> but when I try to access the 'list[n].action' I seem to have nil in the  
> field(s),although looking at 'list' in total seems to show the data.  
> List is ([#\<TodoItem:0x8379f30 @item\_rec=#\<OpenStruct done=false,  
> action="1", name="hgafafgafgagaf"\>\>])

With that structure you rather need to do

list[0].item\_rec.action

don't you? Can you share the code of class TodoItem?

> Is it because I have an array of 'objects' - ie 'list' now contains a  
> single element of class 'TodoItem'? If so, how do I access the  
> 'item\_rec' sub object of 'list'?

See above.

Kind regards

robert

> **···**
>
> On Thu, Nov 22, 2012 at 1:52 PM, Steve Tucknott \<lists@ruby-forum.com\> wrote:
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [22 November 2012 14:37 UTC](https://rubytalk.org/t/arrays-with-records-as-objects/66736/3 "2012-11-22T14:37:56Z")

</div>

Robert

The TodoItem class is as attached.

I'm a complete novice, so I'm not sure how structures are used in Ruby -  
I had tried a simple case of '..build record...put in array' in another  
example where I built a local record and appended that to a local array,  
and then I accessed the array fields by a simple array[n].field1. So I  
stupidly assumed that the similar '@list \<\< item\_rec' would append the  
structure of item\_rec in the list array.

Attachments:  
[http://www.ruby-forum.com/attachment/7888/TodoItem.rb](http://www.ruby-forum.com/attachment/7888/TodoItem.rb)

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [22 November 2012 17:06 UTC](https://rubytalk.org/t/arrays-with-records-as-objects/66736/4 "2012-11-22T17:06:39Z")

</div>

Robert,  
Thanks for the informative replies - very much appreciated.

I am 'playing'/'learning' at the moment - so what I have been doing is  
taking base examples and then adding how I could use them in the 'real  
world'.

In an earlier array example, I had used the record Openstruct structure  
as:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# -- This is my test to see how arrays can be indexed.....a  
five element array  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# -- for names and address/post code  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr = []

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for i in 0..5  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec = OpenStruct.new  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec.name = "Cust#{i+1}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec.line1 = "C#{i+1}Line1"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec.line2 = "C#{i+1}Line2"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec.line3 = "C#{i+1}Line3"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec.line4 = "C#{i+1}Line4"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec.pcode = "C#{i+1}PCode"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr[i] = addr\_rec  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for i in 0..(addr.length-1)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`zenity --info --title="My Array" --text="Each Array  
Element:\n#{addr[i].name}\n#{addr[i].line1}\n#{addr[i].line2}\n#{addr[i].line3}\n#{addr[i].line4}\n#{addr[i].pcode}"`  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

So, because that seemed to work ok, I then wanted to try to represent  
the TodoList file line contents as a 'record' (in general, that is how  
I'm used to handling file data). Hence then getting the 'line' record  
into the array.

In between postings though, I did remove the record structure, and made  
the item three separate instance variables again.  
So I think I'll create two versions of this - the single variables and  
record structure options.

All the STDOUTs are my debug lines (as well as the main zenity system  
calls) to see what is going on.

The 'toggle' on the status is driven by a zenity window - a checkbox  
just marks 'Done' - but I see what you mean.

Thanks for the info on the ternary operator - and I'll look into logger  
calls and create an example for that!

Is there a separate forum that you know of for complete Ruby newbies  
like me?

Thanks again for your help.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [23 November 2012 12:49 UTC](https://rubytalk.org/t/arrays-with-records-as-objects/66736/5 "2012-11-23T12:49:47Z")

</div>

Thanks for all the advice.

Bear in mind though, that in some cases (not all!) the poor coding was  
simply because I cut and pasted a line (ie the build of addr\_rec) - I  
wouldn't write code like that in working code. I'll make notes though to  
the best practice in my test examples (actually it's now one example as  
I thought I'd bolt all the examples into one module and use arguments  
and a case to drive it - just to see how arguments and case worked! -  
once I know how to create libraries, I'll split them back out again!)

What I've found odd so far is that Ruby appears to have multiple ways of  
doing the same thing - so as you say, I could write:  
line[i] = some\_rec  
or  
line \<\< some\_rec  
(assuming the index points to the next empty slot)

..and the examples don't appear (so far) to explain the why's and  
where's and then best practices.

Ditto for iteration.

All this is my fault , as I was up to array handling, and then googled  
something I didn't quite follow - and ended up at a site with a 'todo'  
example that I thought would be good as a mini test module. So I jumped  
ahead of myself and started faffing around with that and then hit  
records in arrays etc.

Such is the learning curve.

Thanks for your patience.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [24 November 2012 17:02 UTC](https://rubytalk.org/t/arrays-with-records-as-objects/66736/6 "2012-11-24T17:02:30Z")

</div>

So far so good.  
I now have my 'Tutorial' test module working from a looping case, with  
sub options (based mainly on the examples at [rubylearning.com](http://rubylearning.com), and my To  
Do list).

The ToDo list (that now has a action number (as a reversed date) and  
text) stored in a file - with the actions being updateable.

I did have one further issue with my list array - when selecting from a  
Zenity list, Zenity returns a comma separated list of column entries.  
In my case, my new 'action no' was the column(s) returned. I could then  
split the returned string to get the individual action numbers - but I  
couldn't find an elegant way of then getting which entry in the list  
array matched that action no to mark it as done.  
I did see there was an 'index' method, but I could see how that worked  
with a multi-column array (my list has columns of done, action no and  
text) - so I wanted to do a find like (pseudo code):  
list.action.find("20121123110100")  
..that code failed (errored) and list.find("valid value") returned nil.

I got a working example by iterating over the list array and manually  
comparing the list[n].action to the Zenity returned values.

Is there a way of 'finding' (and getting the index value of the array  
line) a value in a specific column in a multi-column array that you  
know of?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [25 November 2012 10:36 UTC](https://rubytalk.org/t/arrays-with-records-as-objects/66736/7 "2012-11-25T10:36:10Z")

</div>

Far more elegant!  
I'll bolt that into my code and see what I get.

Thanks again, Obi Wan.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Tamara\_Temple1](https://avatars.discourse-cdn.com/v4/letter/t/5f9b8f/32.png) [@Tamara\_Temple1](https://rubytalk.org/u/Tamara_Temple1)\
**Post date:** [22 November 2012 16:26 UTC](https://rubytalk.org/t/arrays-with-records-as-objects/66736/8 "2012-11-22T16:26:42Z")

</div>

Steve,

I'm probably not understanding what you're trying to do here, but why  
do you use the OpenStruct class here?

I think the question of how to access an anonymous object in an array  
is still an interesting one. I think you have to give @item\_rec  
accessors (maybe just attr\_reader? not sure). The attr\_accessor's you  
have set for :done, :action, and :name define instance variables  
directly in TodoItem, but then you create a new object @item\_rec and  
assign instance variables to it. This results is your class really  
having 4 instance variables, not 3, only 3 of which aren't being used:

TodoItem instance vars:  
@done - not used by class  
@action - not used by class  
@name - not used by class  
@item\_rec - this is used

The object @item\_rec points to has 3 instance variables:  
@done  
@action  
@name

So, if you replace the attr\_accessor line with:

attr\_accessor :item\_rec

Then, in your outer code, you can refer to it with the list as:

@list[0].item\_rec.name

Still, unless this is an exercise in using OpenStruct, it's quite unnecessary.

Instead, you can simply do this:

class TodoItem  
&nbsp;&nbsp;&nbsp;&nbsp;attr\_accessor :done, :action, :name  
&nbsp;&nbsp;&nbsp;&nbsp;alias\_method :done?, :done

&nbsp;&nbsp;&nbsp;&nbsp;def initialize(line)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Create a record of state, action and name with state (done)  
set to false  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# set state to undone  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@done = false  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@action, @name = line.split("\<\<\>\>")  
&nbsp;&nbsp;# Generally not a good idea to have object print out internal state like this  
&nbsp;&nbsp;# It can be useful for debugging, but better to define a  
&nbsp;&nbsp;# to\_s method that will format it how you like it  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# STDOUT.puts "New TodoItem - #{@item\_rec}"  
&nbsp;&nbsp;# if this really is debugging info, consider using a  
&nbsp;&nbsp;# logger instead of tossing it to STDOUT  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;# maybe this is personal, but I'd call this state?  
&nbsp;&nbsp;&nbsp;&nbsp;# also, look at the ternary operator. the following could be written  
&nbsp;&nbsp;&nbsp;&nbsp;# @done ? "Done" : "Active"  
&nbsp;&nbsp;&nbsp;&nbsp;def state\_getter  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if @done  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Done"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Active"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;# You might consider a more descriptive set of methods  
&nbsp;&nbsp;&nbsp;&nbsp;# that say what is happening, such as "complete" and "undo"  
&nbsp;&nbsp;&nbsp;&nbsp;# rather than the single method to flip the value.  
&nbsp;&nbsp;&nbsp;&nbsp;# flipping rather depends on the current state, obviously,  
&nbsp;&nbsp;&nbsp;&nbsp;# but it thus requires proper knowlege of the current  
&nbsp;&nbsp;&nbsp;&nbsp;# state to determine what to do. methods like "complete" and  
&nbsp;&nbsp;&nbsp;&nbsp;# "undo" state more clearly their intentions.  
&nbsp;&nbsp;&nbsp;&nbsp;def state\_setter  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STDOUT.puts "Setter Status Was ("+@item\_rec.done+") for  
("+@item\_rec.name+')'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@item\_rec.done = !@item\_rec.done  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STDOUT.puts "Setter Status Now ("+@item\_rec.done+") for  
("+@item\_rec.name+')'  
&nbsp;&nbsp;&nbsp;&nbsp;end

end

> **···**
>
> On Thu, Nov 22, 2012 at 8:37 AM, Steve Tucknott \<lists@ruby-forum.com\> wrote:
> 
> > Robert
> > 
> > The TodoItem class is as attached.
> > 
> > I'm a complete novice, so I'm not sure how structures are used in Ruby -  
> > I had tried a simple case of '..build record...put in array' in another  
> > example where I built a local record and appended that to a local array,  
> > and then I accessed the array fields by a simple array[n].field1. So I  
> > stupidly assumed that the similar '@list \<\< item\_rec' would append the  
> > structure of item\_rec in the list array.
> > 
> > Attachments:  
> > [http://www.ruby-forum.com/attachment/7888/TodoItem.rb](http://www.ruby-forum.com/attachment/7888/TodoItem.rb)

---

<div class="post-metadata">

**Author:** ![Tamara\_Temple1](https://avatars.discourse-cdn.com/v4/letter/t/5f9b8f/32.png) [@Tamara\_Temple1](https://rubytalk.org/u/Tamara_Temple1)\
**Post date:** [22 November 2012 21:55 UTC](https://rubytalk.org/t/arrays-with-records-as-objects/66736/9 "2012-11-22T21:55:34Z")

</div>

> I am 'playing'/'learning' at the moment - so what I have been doing is  
> taking base examples and then adding how I could use them in the 'real  
> world'.

This is great!! Experimenting with stuff that your learning is a great  
thing, and no way would I want to discourage that. Checking in with  
what your learning is a great thing, too.

> In an earlier array example, I had used the record Openstruct structure  
> as:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# -- This is my test to see how arrays can be indexed.....a  
> five element array  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# -- for names and address/post code  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr =
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for i in 0..5  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec = OpenStruct.new  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec.name = "Cust#{i+1}"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec.line1 = "C#{i+1}Line1"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec.line2 = "C#{i+1}Line2"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec.line3 = "C#{i+1}Line3"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec.line4 = "C#{i+1}Line4"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr\_rec.pcode = "C#{i+1}PCode"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr[i] = addr\_rec  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for i in 0..(addr.length-1)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`zenity --info --title="My Array" --text="Each Array  
> Element:\n#{addr[i].name}\n#{addr[i].line1}\n#{addr[i].line2}\n#{addr[i].line3}\n#{addr[i].line4}\n#{addr[i].pcode}"`  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> So, because that seemed to work ok, I then wanted to try to represent  
> the TodoList file line contents as a 'record' (in general, that is how  
> I'm used to handling file data). Hence then getting the 'line' record  
> into the array.

It does work, yet it might not be the best way to do things in the  
ruby world. Looking at the above, it seems to be borrowing idioms from  
other 'less expressive' languages than ruby.

For instance, for loops are almost never needed in ruby. To approach a  
more idiomatic ruby expression of the above, you would use the "each"  
method:

0..5.each do |i| # a range creates an iterator,  
usable by each  
&nbsp;&nbsp;addr\_rec = OpenStruct.new  
&nbsp;&nbsp;cnum = i+1 # calculating the "customer number" once  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# rather than recalculating it for each  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# field below  
&nbsp;&nbsp;addr\_rec.name = "Cust#{cnum}"  
&nbsp;&nbsp;addr\_rec.line1 = "C#{cnum}Line1"  
&nbsp;&nbsp;addr\_rec.line2 = "C#{cnum}Line2"  
&nbsp;&nbsp;addr\_rec.line3 = "C#{cnum}Line3"  
&nbsp;&nbsp;addr\_rec.line4 = "C#{cnum}Line4"  
&nbsp;&nbsp;addr\_rec.pcode = "C#{cum}PCode"  
&nbsp;&nbsp;addr[i] = addr\_rec  
&nbsp;&nbsp;# this could also be written as:  
&nbsp;&nbsp;# addr \<\< addr\_rec  
end

addr.each do |a| # an array also has an  
iterator, also usable by each  
&nbsp;&nbsp;`zenity --info --title="My Array" --text="Each Array  
Element:\n#{a.name}\n#{a.line1}\n#{a.line2}\n#{a.line3}\n#{a.line4}\n#{a.pcode}"`  
end

Note the comment about calculating cnum; in general it's best to  
calculate a local constant once, rather than several times. It  
wouldn't surprise me if the above was optimized away under the hood,  
but it's best not to rely on such things, and it's more expressive of  
what you mean by giving it it's own variable name

> In between postings though, I did remove the record structure, and made  
> the item three separate instance variables again.  
> So I think I'll create two versions of this - the single variables and  
> record structure options.
> 
> All the STDOUTs are my debug lines (as well as the main zenity system  
> calls) to see what is going on.

Another way to approach this, rather than inserting debug statements  
you will later have to remove from code if you're going to use it in  
an application, is to follow a technique known as Test Driven  
Development. The ruby community has, more than any other I've  
encountered, embraced testing as a way of life, and the best practice.  
The idea that you write down how you are going to test something helps  
tremendously in figuring out what you want the code to do. While  
you're experimenting and just trying things out, it can seem like a  
bit of a hindrance, yet establishing the habit early can be quite  
beneficial.

Essentially, with the TodoItem class, instead of printing out the  
debug statements, you could write test code that verified the  
behaviour of the methods. There are some great ruby test gems, a lot  
of people use RSpec because of the neat way you write tests, but even  
a "poor man's" test program is possible, and in just starting out,  
maybe more helpful.

In a test script, making a call like:

item = TodoItem.new("1\<\<\>\>a new item")

You can then debug/test that item was created successfully, doing  
something like:

puts "done = #{item.done}"  
puts "action = #{item.action}"  
puts "name = #{item.name}"  
puts "state is = #{item.state\_getter}"  
item.state\_setter  
puts "state is now #{item.state\_getter}"

Also, if you haven't, do try out the ruby console, irb. You can  
quickly throw ruby expressions like this at it and see what happens.

> Is there a separate forum that you know of for complete Ruby newbies  
> like me?

Here is good -- we all learn from each other!

There are lots of great resources out there, but I think interacting  
with real people is great way to learn the subtler nuances of things,  
such as the each method if you're coming from a standard procedure  
programming approach; in learning to use a language, the idioms that  
are best used in that language are sometimes not that apparent. That's  
where knocking heads with others helps a lot.

I'm also firmly of the belief that you can't \*really\* master something  
unless you can teach it. So do me a favour and stick around. 🙂

(and, crikey, i'm having fun, too 🙂 )

> **···**
>
> On Nov 22, 2012 11:07 AM, "Steve Tucknott" \<lists@ruby-forum.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Tamara\_Temple1](https://avatars.discourse-cdn.com/v4/letter/t/5f9b8f/32.png) [@Tamara\_Temple1](https://rubytalk.org/u/Tamara_Temple1)\
**Post date:** [24 November 2012 12:05 UTC](https://rubytalk.org/t/arrays-with-records-as-objects/66736/10 "2012-11-24T12:05:16Z")

</div>

> Thanks for all the advice.

My pleasure. 🙂

> Bear in mind though, that in some cases (not all!) the poor coding was  
> simply because I cut and pasted a line (ie the build of addr\_rec) - I  
> wouldn't write code like that in working code.

That was understood -- I was merely trying to point out that such  
things do leak into "real" code. Even when we're just learning, or  
even playing around, it can help to keep the "discipline" if you will.  
But I'm glad you see the difference!

> I'll make notes though to  
> the best practice in my test examples (actually it's now one example as  
> I thought I'd bolt all the examples into one module and use arguments  
> and a case to drive it - just to see how arguments and case worked! -  
> once I know how to create libraries, I'll split them back out again!)
> 
> What I've found odd so far is that Ruby appears to have multiple ways of  
> doing the same thing

Nearly every language I've come across this is true. The richness of  
expression is a good thing, in my view.

> - so as you say, I could write:  
> line[i] = some\_rec  
> or  
> line \<\< some\_rec  
> (assuming the index points to the next empty slot)
> 
> ..and the examples don't appear (so far) to explain the why's and  
> where's and then best practices.

It's somewhat a matter of taste, sometimes a real boon to programming.

The latter is the classic "push" type of operation -- very useful when  
you just want to append without knowing the current end of the array.

> Ditto for iteration.
> 
> All this is my fault , as I was up to array handling, and then googled  
> something I didn't quite follow - and ended up at a site with a 'todo'  
> example that I thought would be good as a mini test module. So I jumped  
> ahead of myself and started faffing around with that and then hit  
> records in arrays etc.

I wouldn't consider it a fault -- as in laying blame or guilt or  
anything like that. We all have our own learning style, and our own  
way of approaching things. Jumping around can be useful, or you can  
miss something, but it all works out, eventually.

> Such is the learning curve.
> 
> Thanks for your patience.
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

I really hope I'm not discouraging you. This is actually fun stuff.  
Take my comments for what they are, merely trying to help you up the  
curve a bit. The best part about free advice is you don't have to take  
it.

> **···**
>
> On Fri, Nov 23, 2012 at 6:49 AM, Steve Tucknott \<lists@ruby-forum.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Tamara\_Temple1](https://avatars.discourse-cdn.com/v4/letter/t/5f9b8f/32.png) [@Tamara\_Temple1](https://rubytalk.org/u/Tamara_Temple1)\
**Post date:** [25 November 2012 02:32 UTC](https://rubytalk.org/t/arrays-with-records-as-objects/66736/11 "2012-11-25T02:32:59Z")

</div>

Yes, and it's a doozy 🙂

if you know the action number, say "20121123110100" in your example:

list.index { |l| l.action == "20121123110100" } # =\> array index

yields the index in the array list that matches the first item.

The "{..}" is a block, which is a group of code. This group is only  
one statement, the test for equality. the "|l|" defines a paramter to  
use in the block of code. The method "index" operates on the block of  
code like the "each" method seen earlier, but in this case, instead of  
just iterating, it returns the array index where the block returns a  
true value.

Now, if instead of the array index, you wanted the actual object, you  
would use the "select" method:

list.select { |l| l.action == "20121123110100" } # =\> {TodoItem object}

> **···**
>
> On Sat, Nov 24, 2012 at 11:02 AM, Steve Tucknott \<lists@ruby-forum.com\> wrote:
> 
> > Is there a way of 'finding' (and getting the index value of the array  
> > line) a value in a specific column in a multi-column array that you  
> > know of?
