swingfuture
swingfuture

Reputation: 1108

Symbol Replacement in Ruby

I have a map generated by others with data structure like this:

x = {"city": "London", "country": "England", "region": "Europe"}

I want to manipulate the data in Ruby. So in order to be able to let Ruby understand it's a map, I need to replace all ":" to "=>". Is there a quick way to accomplish this in one line?

Upvotes: 0

Views: 2370

Answers (4)

rampion
rampion

Reputation: 89043

Another alternative, if you wanted to minimize your vulnerability to #eval (which is a rational thing to do) is to use String#scan:

quoted = /"(?:\\.|[^\\"])*"/
pairs = '{"city": "London", "country": "England", "region": "Europe"}'.scan(/(#{quoted})\s*:\s*(#{quoted})/)
hash = Hash[ *pairs.flatten.map { |q| eval q } ]

We're still using #eval, but we know that we're only #eval'ing something that looks like a quoted string, so we're safe-ish. Since ruby strings can contain arbitrary code (through the miracle of interpolation), we're still vulnerable, though:

# arbitrary code evaluation
p eval('"one two #{puts %{Give me a three!}; gets.chomp} four"')

The safest alternative is to bypass #eval entirely, and use a library for unquoting strings that doesn't allow for interpolation. The JSON library (as previously mentioned) is a great example of that. It may seem slower (since it's not as optimized as #eval is), but it's a whole heck of a lot safer.

Upvotes: 0

Subba Rao
Subba Rao

Reputation: 10676

you need to install this gem json

sudo gem install json

    require 'json'
    JSON.parse('{"city": "London", "country": "England", "region": "Europe"}')

Upvotes: 13

collimarco
collimarco

Reputation: 35379

my_text = 'x = {"city": "London", "country": "England", "region": "Europe"}'

# Replace : with =>
ruby_code = t.gsub(':', '=>')

# Evaluate the string as ruby code
eval ruby_code

# Now you can access the hash

x['city'] # => "London"

Upvotes: 5

mipadi
mipadi

Reputation: 410552

'{"city": "London", "country": "England", "region": "Europe"}'.gsub!(/: /, ' => ')

gsub! does an in-place global substitution on the string.

Upvotes: 2

Related Questions