OT: How to make this code prettier?

This isn't specific to Rails, but I would like to learn from the experience of others.

How would you make this code prettier...

Docdesc = Struct.new(:document_category_id,                      :document_number_prefix,                      :primary_part_number,                      :document_family_series,                      :description,                      :revision,                      :release_status,                      :originator,                      :docdate) ... row = some_array_of_strings_ints_and_floats()         dd = Docdesc.new         dd.document_category_id = c.id         dd.document_number_prefix = row[0].to_s unless row[0].nil?         dd.primary_part_number = row[1].to_s unless row[1].nil?         dd.document_family_series = row[2].to_s unless row[2].nil?         dd.description = row[3].to_s unless row[3].nil?         dd.revision = row[4].to_s unless row[4].nil?         dd.release_status = row[5].to_s unless row[5].nil?         dd.originator = row[6].to_s unless row[6].nil?         dd.docdate = row[7].to_s unless row[7].nil?

--wpd

Something = Struct.new(:one, :two, :three)

index = 0 for x in %w{ one= two= three= }   dd.send x, row[ index ]   index += 1 end

Something = Struct.new(:one, :two, :three)

index = 0 for x in %w{ one= two= three= }   dd.send x, row[ index ]   index += 1 end

Thanks for the suggestion. I thought (a very little bit) about quoting the member names of the structure, but, where they are rather long, I thought the %w{some_very_long_name, some_other_very_log_name, etc..} looked a little unwieldy, and not any prettier than what I started with, (especially when one has to remember to tack on the equal sign at the end of each name).

Gently guiding this back onto the topic of Rails... later in my code, I want to initialize an ActiveRecord object from my Struct element. I tried this:

dbdoc = Document.new(doc.hash)

Where Document looks like:

class Document < ActiveRecord::Base   belongs_to :document_category end

and doc is instance of my structure I defined previously. However, when I try this, I get an exception:

.../activerecord-2.0.2/lib/active_record/base.rb:2110:in `dup': can't dup Fixnum (TypeError)

So I am left with:

          dbdoc = Document.new           dbdoc.document_category_id = doc.document_category_id           dbdoc.document_number_prefix = doc.document_number_prefix           dbdoc.primary_part_number = doc.primary_part_number           dbdoc.document_family_series = doc.document_family_series           dbdoc.description = doc.description           dbdoc.revision = doc.revision           dbdoc.release_status = doc.release_status           dbdoc.originator = doc.originator           dbdoc.docdate = doc.docdate

which, again, looks uglier than I think it should.

Any suggestions?

Well if you know that the column/field names will always match up you can use the fact that struct mixes in enumerable, so for example you can do doc.each_pair do |name, value|   dbdoc.send(name.to_s + '=', value) end You could also use that to build up a hash that you could give to Document.new

Fred

> dbdoc = Document.new > dbdoc.document_category_id = doc.document_category_id > dbdoc.document_number_prefix = doc.document_number_prefix > dbdoc.primary_part_number = doc.primary_part_number > dbdoc.document_family_series = doc.document_family_series > dbdoc.description = doc.description > dbdoc.revision = doc.revision > dbdoc.release_status = doc.release_status > dbdoc.originator = doc.originator > dbdoc.docdate = doc.docdate > > which, again, looks uglier than I think it should.> Well if you know that the column/field names will always match up you

I can (and have) make that to be the case

can use the fact that struct mixes in enumerable, so for example you can do doc.each_pair do |name, value|   dbdoc.send(name.to_s + '=', value) end

That's clever. But is it more readable? If it is idiomatic Ruby, then I would say "yes it is more readable". Being rather new to Ruby and not having read any production Ruby code, I don't know if that's idiomatic or not.

You could also use that to build up a hash that you could give to Document.new

That's what I tried originally:

dbdoc = Document.new(doc.hash)

but that threw an exception: .../activerecord-2.0.2/lib/active_record/base.rb:2110:in `dup': can't dup Fixnum (TypeError)

--wpd

> > dbdoc = Document.new > > dbdoc.document_category_id = doc.document_category_id > > dbdoc.document_number_prefix = doc.document_number_prefix > > dbdoc.primary_part_number = doc.primary_part_number > > dbdoc.document_family_series = doc.document_family_series > > dbdoc.description = doc.description > > dbdoc.revision = doc.revision > > dbdoc.release_status = doc.release_status > > dbdoc.originator = doc.originator > > dbdoc.docdate = doc.docdate

> > which, again, looks uglier than I think it should.> > Well if you know that the column/field names will always match up you

I can (and have) make that to be the case

> can use the fact that struct mixes in enumerable, so for example you > can do > doc.each_pair do |name, value| > dbdoc.send(name.to_s + '=', value) > end

That's clever. But is it more readable? If it is idiomatic Ruby, then I would say "yes it is more readable". Being rather new to Ruby and not having read any production Ruby code, I don't know if that's idiomatic or not.

It's either readable or not, make your own mind up about it :slight_smile: It doesn't make a lot of sense to have someone else tell you if something is readable: if you find it readable then that should be good enough for you. slightly cuter is doc.each_pair {|name, value| dbdoc[name]=value} but it's not quite the same things (since it just writes the attribute rather than calling any custom accessor you may have created)

> You could also use that to build up a hash that you could give to > Document.new

That's what I tried originally:

dbdoc = Document.new(doc.hash)

but that threw an exception: .../activerecord-2.0.2/lib/active_record/base.rb:2110:in `dup': can't dup Fixnum (TypeError)

That's not what hash does. hash returns an integer (such that a.hash ! = b.hash => a != b) which is used when storing things like that in a hash. If you want a hash you need to iterate over the struct and build it typ.

Fred