You could use the JSON module to do that. That would arguably be safer than by using eval.
To see how JSON could be used, let's do some reverse-engineering. You want to create a hash:
h = { :cost=>100, :size=>2 }
from the string:
str = '[{":cost=>100", ":size=>2"}]'
#=> "[{\":cost=>100\", \":size=>2\"}]"
Let's see how that hash would be encoded as a JSON string:
require 'json'
jstr = JSON.generate(h)
#=> "{\"cost\":100,\"size\":2}"
Once we have jstr (which is nothing more than a string) we can extract the desired hash:
JSON.parse(jstr)
#=> {"cost"=>100, "size"=>2}
so the task reduces to converting str to jstr:
"[{\":cost=>100\", \":size=>2\"}]" => "{\"cost\":100,\"size\":2}"
Perhaps the easiest way is to first pull out the keys and values, which we can do with a regex:
r = /
( # start capture group 1
[a-z] # match a lowercase letter
\w* # match >= 0 word characters
) # close capture group 1
=> # match characters
(-?\d+) # optionally match a minus sign followed by > 0 digits in
# capture group 2
/x # free-spacing regex definition mode
arr = str.scan r
#=> [["cost", "100"], ["size", "2"]]
We can now form jstr:
jstr = "{#{ arr.map { |k,v| "\"#{k}\":#{v}" }.join(",") }}"
#=> "{\"cost\":100,\"size\":2}"
To confirm,
h = JSON.parse(jstr)
#=> {"cost"=>100, "size"=>2}
{}.eval('{' + [":cost=>100", ":size=>2"].join(',') + '}')?you_obj.to_syou get"[{\":cost=>100\", \":size=>2\"}]"?