Ruby Best Practices

Page 276

When you require strscan, it provides a class called StringScanner. The underlying purpose of using this object is that it keeps track of where you are in the string as you consume parts of it via regex patterns. Just to clear up what this means, we can take a look at the example used in the RDoc: s = StringScanner.new('This is an example string') s.eos? # -> false p s.scan(/\w+/) p s.scan(/\w+/) p s.scan(/\s+/) p s.scan(/\s+/) p s.scan(/\w+/) s.eos?

# # # # # #

-> -> -> -> -> ->

"This" nil " " nil "is" false

p s.scan(/\s+/) p s.scan(/\w+/) p s.scan(/\s+/) p s.scan(/\w+/) p s.scan(/\s+/) p s.scan(/\w+/) s.eos?

# # # # # # #

-> -> -> -> -> -> ->

" " "an" " " "example" " " "string" true

p s.scan(/\s+/) p s.scan(/\w+/)

# -> nil # -> nil

From this simple example, it’s clear to see that the index is advanced only when a match is made. Once the end of the string is reached, there is nothing left to match. Although this may seem a little simplistic at first, it forms the essence of what StringScanner does for us. We can see that by looking at how it is used in the context of something a little more real. We’re about to look at how to parse JSON (JavaScript Object Notation), but the example we’ll use is primarily for educational purposes, as it demonstrates an elegant use of StringScanner. If you have a real need for this functionality, be sure to look at the json standard library that ships with Ruby, as that is designed to provide the kind of speed and robustness you’ll need in production. In Ruby Quiz #155, James Gray builds up a JSON parser by hand-rolling a recursive descent parser using StringScanner. He actually covers the full solution in depth on the Ruby Quiz website, but this abridged version focuses specifically on his use of StringScanner. To keep things simple, we’ll discuss roughly how he manages to get this small set of assertions to pass: def test_array_parsing assert_equal(Array.new, @parser.parse(%Q{[]})) assert_equal( ["JSON", 3.1415, true], @parser.parse(%Q{["JSON", 3.1415, true]}) ) assert_equal([1, [2, [3]]], @parser.parse(%Q{[1, [2, [3]]]})) end

We can see by the general outline how this parser works:

260 | Appendix B: Leveraging Ruby’s Standard Library


Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.