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 <[email protected]> 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 [email protected].
To post to this group, send email to [email protected].
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.

Reply via email to