Structs with type-casting in Ruby
Sometimes you have some data like this:
Dave,32,employee,15.75
Harris,23,employee,15.75
Mary,38,supervisor,21.25
And you organize it with a Struct object:
require 'csv'
Person = Struct.new :name, :age, :category, :wage
people = CSV.parse(data).map { |args| Person.new(*args) }
But, your data ends up looking like this:
#<struct Person name="Dave", age="32", category="employee" ... >
#<struct Person name="Harris", age="23", category="employee" ... >
...
Wouldn't it be nice to have Struct automatically cast each argument to a specified data type? Lacking any ubiquitous method for casting data in Ruby, we can do the next best thing and specify a method to call. Meet CastingStruct:
class CastingStruct < Struct
def self.new(hash, &blk)
super(*hash.keys) do
define_method :initialize do |*args|
super *hash.values.map { |method|
args.shift.public_send method
}
end
class_eval(&blk) if blk
end
end
end
Now you can create a struct that takes a hash in the format field_name => method.
Person = CastingStruct.new name: :to_s,
age: :to_i,
category: :to_sym,
wage: :to_f
people = CSV.parse(data).map { |args| Person.new(*args) }
Now the object in each field is an instance of the correct class
irb> people.first
=> #<struct Person name="Dave", age=32, category=:employee, wage=15.75>
irb> people.first.category.class
=> Symbol
Much better :)
Written by Will Spitzer
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Ruby
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#