Hi,
I’m trying to write some convenience methods for one of my classes. My
class has an array of objects, each of which points to another object
that I am interested in. (I’m describing an Active Record has_many
relationship… you can skip ahead if you like.) According to this
setup I can write
list.middlemen[1].item
to access the first item in the list. Iterating through my items would
be accomplished by
list.middlemen.collect {|middleman| middleman.item}.each
and setting the first item in the list to a different item is
complicated:
list.middlemen[1]= Middleman.new {:item => newitem}
That’s it for the setup. The convenience methods I want to write would
accomplish those same three tasks but written like this:
list.items[1]
list.items.each
list.items[1]= new_item
Defining the first two of these conveniences is simple, within the List
class, I just use a wrapper called ‘items’ that returns an array of my
items.
def items
middlemen.collect {|middleman| middleman.item}
end
[[The Juicy Bit]]
But the last one is nasty. When I try to define this:
def items[]= (index, newitem)
…doesn’t matter what’s here…
end
I get a syntax error on the method name at the brackets. I could just
define []= on my List class, as I don’t have anything else conflicting
there, but it seems messy to talk about items sometimes and not always.
And I definitely want to be able to return an array by calling the
List.items instance method.
What I really want is for the items method to act like an attr_accessor
on the array generated by
middlemen.collect {|middleman| middleman.item}
and for assignments made to the generated array to effect the objects
that the middlemen point to with their ‘item’ method. (with my current
setup, alteration made to properties of items stick, but
assignment/replacing of whole items does not).
eg:
list.items[1].title #=> ‘an original item’
list.items[1].title= ‘changed title’
gives:
list.items[1].title #=> ‘changed title’
but then running:
new_item = Item.create {:title => ‘a new item’}
list.items[1]= new_item
still results in:
list.items[1].title #=> ‘changed title’
I know this is long, and the problem is not completely defined, but
this seems like a common enough problem, and I’ve had little luck
searching the web for it. I imagine the same problem will hold for the
<< method and others.
Perhaps I should investigate another direction?
Thanks for any pointers!
Chris