On 9/9/06, Christer Nilsson <janchrister.nilsson / gmail.com> wrote:
> I'm trying to communicate with a bank. Banks are still using the punched
> card layout in their files.
>
> Example: 001234567800023420060909
> (account=12345678, amount=234 and day=20060909)
>
> I'm trying to make some nice Ruby classes to handle this.
>
> I would like to define the class like this (compare attr)
>
> class Trans < Record
>   field :account, 10
>   field :amount, 6
>   field :lastday, 8
> end
>
> This is what I've been able to do:
> There are several problems: As the fields have to be in a certain order
> a hash will not work. On the other hand, looping through an array takes
> time.

Could you expand on that a bit further? What are you trying to
optimise for? If you want an O(1) accessor for say, [:account] you
could use one of the several OrderedHash implementations posted here
recently (check google groups - there was a long thread), or simply
maintain a separate hash { :account => 1, :amount => 2, :lastday => 3
} and use that to index into the array of fields.

It seems to me that you could get away with a hash of the form :field
=> [start, end], coupled with an array giving the ordering of the
fields (for when you want to iterate over all the fields), and store
Then you could access an individual field thus:
class Record
  def initialize(str)
    @record = str
    @field_limits = {}
    @fields = []
  end

  def [](field)
    start, end = @field_limits[field]
    @record[start..end]
  end

  def []=(field, value)
    start, end = @field_limits[field]
    value = pad(value, end-start)
    @record[start..end] = value
  end
end

martin