Ruby on Rails Monday, August 26, 2013

On 2013-Aug-26, at 17:10 , Love U Ruby wrote:

> tamouse m. wrote in post #1119628:
>> On Aug 26, 2013, at 2:42 PM, Love U Ruby <lists@ruby-forum.com> wrote:
>>
>>
>> You have a string which represents a what a Hash looks like. Why not run
>> it through eval and see what you get?
>>
>> my_hash = eval(new_str)
>
> I was trying to avoid `eval`. I tried also the `yaml`. But no luck :(


If all your keys and values are just digits (i.e., String#to_i likes them), then you can easily avoid eval and yaml. Just make your own parser. Here are some "learning tests" to get you started. If you avoid scrolling down too far to see my "answer", then just make the tests pass and you're done!

Of course, you can also expand the tests to cover even more exotic hash keys and values, but if you go too far you've just reinvented YAML or JSON with different syntax.

-Rob


require 'minitest/autorun'

class TestSomeCrappyMarkupLanguage < Minitest::Test
def setup
@str = "1=2,3=(4=5,6=7)"
end

def test_nil
refute SomeCrappyMarkupLanguage.parse(nil)
end

def test_empty_string
assert_equal({}, SomeCrappyMarkupLanguage.parse(""))
end

def test_simple_hash
assert_equal({1=>2}, SomeCrappyMarkupLanguage.parse("1=2"))
end

def test_two_elements
assert_equal({4=>5,6=>7}, SomeCrappyMarkupLanguage.parse("4=5,6=7"))
end

def test_nested
expected = { 1 => 2, 3 => { 4 => 5, 6 => 7 } }
assert_equal expected, SomeCrappyMarkupLanguage.parse(@str)
end

end

# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...
# spoilers below...

class SomeCrappyMarkupLanguage
def self.parse(str)
return nil unless str
result = {}
str.scan(/(\d+)=((?:\([^\)]*\))|\d+),?/).each do |key,value|
key = key.to_i
value = value =~ /\A\d+\z/ ? value.to_i : parse(value)
result[key] = value
end
result
end
end


--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe@googlegroups.com.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/B705512C-FD76-4F45-BE2D-81DD0904DCA0%40agileconsultingllc.com.
For more options, visit https://groups.google.com/groups/opt_out.

No comments:

Post a Comment