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.25And 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
endNow 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
=> SymbolMuch 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#

 
 
 
 
