Konstantin
Konstantin

Reputation: 3123

Is there any data structure in Ruby which is similar to Pascal records?

Is there any data structure in Ruby which is similar to Pascal records?

I would like to define a record type which has about 15-20 fields, all of them are strings.

I tried to define a class for this purpose, but I realized that I have to define getter and setter methods:

class Data
   def description
        @description
   end

   def size
        @size
   end

   def address
        @address
   end

   .
   .  all other (about 15 variables...)
   . 

   def description=( value )
        @description = value
   end

   def size=(value)
        @size=value
   end

   def address=(value)
        @address=value
   end
  .
  . more setter method (about 15 times...)
  .

end

To define all the 15-20 fields and getters/setters this way is quite annoying. Is there any shorter way to do it? For example:

class Data
 desc, size, address=""
end

Or something similar, and then I would be able to create a new instance of the Data class:

d=Data.new

and then set the instance variables:

d.desc="bla"
d.size="50.66"
d.address="Bla street 20."

I already have a method, that can parse an XML file with the XMLSimple gem, and I would like to create a record (or class) from the parsed data and return it back with the "return" keyword. Then I want to access the fields of the record simply: d.size, d.address, d.description and so on. For example:

def data_import(fname="1.xml")
  data = XmlSimple.xml_in(fname,{'SuppressEmpty' => ""})
  d=Data.new()
  d.desc=data['desc'][0]
  d.size=data['size'][0]
  d.address=data['address'][0]
  d. ... =
  d. ... =  (about 15-20 times)
  d. ... =
  return d
end

my XML (1.xml):

<entity>
 <desc>bla</desc>
 <size>50.66</size>
 <address>Bla street 20.</address>
 .
 . (15-20 more fields)
 .
</entity>

In the Pascal language (and as far as I know in C++) there were a data structure called "record" for this purpose.

Upvotes: 2

Views: 351

Answers (2)

Radu Stoenescu
Radu Stoenescu

Reputation: 3205

You cand use a Hash as a bucket for your attributes/properties or you can make use of Ruby's metaprogramming abilities for generating getters and setters using accessors like this:

attr_accessor :desc, :size, :address

You can also collect the attributes in an array and use splatting like this to expand the array in a list needed by the previously mentioned method:

attributes = [:desc, :size, :address]
attr_accessor *attributes

Upvotes: 1

J&#246;rg W Mittag
J&#246;rg W Mittag

Reputation: 369468

Yes, there is, it uses the C/C++ name instead of record: Struct. Struct is a class factory, if you call Struct.new, it will return a class which has the desired fields:

Data = Struct.new(:description, :size, :address, …)

If you need to modify the behavior, you can pass a block to Struct.new:

Data = Struct.new(:description, :size, :address, …) do
  def my_custom_method; end
end

or use inheritance:

class Data < Struct.new(:description, :size, :address, …)
  def my_custom_method; end
end

Then:

d = Data.new

d.description = …
d.size = …
d.address = …

or alternatively:

d = Data.new(…, …, …)

Upvotes: 1

Related Questions