Is there a valid reason for there not being a method to return the data of a standard ruby struct as a hash (member, value pairs)? Seeing that structs and hashes have very simil
I don't think the use cases for hashes and structs are very similar. A hash lets you store a variable number of key-value pairs, and is suitable for storing thousands of pairs if a you want. No particular key is guaranteed to be present. With a Struct, you always know what the set of "keys" will be and it is usually small (less than 20).
Hashes can be used to associate some piece of information with a large number of different objects. Hashes be used to specify optional parameters to a function. Structs can be used when you want to keep some well-defined pieces of information together in one object.
I've never wanted to convert from the struct to a hash so I'm wondering why you do.
EDIT 1: Did you know you can use this un-hash-like syntax with Structs?
P = Struct.new(:x,:y)
p = P.new(1,2)
p.x # => x
EDIT 2: Hashes can also be used to look up objects quickly. obj_hashed_by_name[name]
can be much faster than obj_array.find { |a| a.name == name }
.
(Ruby <= 1.9.3) OpenStruct
has OpenStruct#marshall_dump and Struct
has Struct#each_pair (use to_a
to get the pairs and Hash
+to_a
to get the hash):
Person = Struct.new(:name, :age)
person = Person.new("Jamie", 23)
person_hash = Hash[person.each_pair.to_a]
#=> {:age=>23, :name=>"Jamie"}
With Ruby 2.0 things are easier: Struct#to_h, OpenStruct#to_h:
Person = Struct.new(:name, :age)
person = Person.new("Jamie", 23)
person_hash = person.to_h
#=> {:age=>23, :name=>"Jamie"}
The accepted answer did not work for me, i used the following instead
require 'ostruct'
require 'date'
lid = OpenStruct.new(:status=>0,:rowversion=>0,:cre_dt=>DateTime.now.to_date,:cre_user=>'9999999')
p Hash[lid.each_pair.to_a] #=> {}
p lid.marshal_dump #=>{:status=>0, :rowversion=>0, :cre_dt=>#<Date: 2014-03-03 ((2456720j,0s,0n),+0s,2299161j)>, :cre_user=>"9999999"}
I guess I don't know why you'd want to do it either, but:
s.members.inject({}) { |m, f| m[f] = s[f]; m }
Or, using each_with_object
:
s.members.each_with_object({}) { |m, h| h[m] = s[m] }