RAML.eval
The RAML.eval() method parses a RAML document using the Kernel.eval. In this way Ruby scripting can still be utilized within the document.
Require the RAML library.
require 'raml'
Given a RAML document:
website "http://rubygems.org"
We can load the text via the #load method. (Note above document text has been placed in the @text variable.)
data = RAML.eval(@text) data.assert == {:website=>"http://rubygems.org"}
One of the nicer features of RAML derives from Ruby’s block notation, allowing for nested entries.
Given a RAML document:
resources do home "http://rubyworks.github.com/raml" docs "http://rubyworks.github.com/raml/docs/api" wiki "http://wiki.rubyworks.github.com/raml" end
We get a two layer hash.
data = RAML.eval(@text) data[:resources][:home].assert == "http://rubyworks.github.com/raml" data[:resources][:docs].assert == "http://rubyworks.github.com/raml/docs/api" data[:resources][:wiki].assert == "http://wiki.rubyworks.github.com/raml"
RAML is also considers the content of a block. If it is a scalar entry, such as a String, then that will be assigned to the key.
Given a RAML document:
description %{ This is a description. It can have multiple lines. RAML handles this just fine, because Ruby does too. }
Loading this document, description will contain the text as expected.
data = RAML.eval(@text) text = data[:description].sub(/\s+/, ' ').strip text.assert.start_with?("This is") text.assert.end_with?("does too.")
It is only unfortunate that Ruby doesn’t have a margin controlled string notation (e.g. `%L{ }`) so that post processing with `sub()` would not be neccessary.
RAML has some options that makes it more flexible than many other data lanaguages. For instance, it can allow for multi-key entries.
Given a RAML document:
source "http://rubygems.org" gem "facets", "~> 2.8" gem "ansi", "~> 1.1"
We simply need to inform the loader to allow identical keys.
data = RAML.eval(@text, :multikey=>true) data.assert == { :source=>"http://rubygems.org", :gem=>[["facets", "~> 2.8"],["ansi", "~> 1.1"]] }
If we did not turn on the multi-key option, then the last `gem` entry would have simply overwritten the former.
data = RAML.eval(@text) data.assert == { :source=>"http://rubygems.org", :gem=>["ansi", "~> 1.1"] }
Not let’s show-off the benefit of using RAML.eval instead of RAML.load.
Given a RAML document:
sum 1 + 1
We will see that the value of `sum` will be evaluated as 2.
data = RAML.eval(@text) data.assert == {:sum=>2}
RAML.read
The RAML.read() method parses a RAML document using Ripper. In this way a RAML document is treated purely as data and cannot contain any Ruby scripting.
Require the RAML library.
require 'raml'
Given a RAML document:
website "http://rubygems.org"
We can load the text via the #read method. (Note above document text has been placed in the @text variable.)
data = RAML.read(@text) data.assert == {:website=>"http://rubygems.org"}
One of the nicer features of RAML derives from Ruby’s block notation, allowing for nested entries.
Given a RAML document:
resources do home "http://rubyworks.github.com/raml" docs "http://rubyworks.github.com/raml/docs/api" wiki "http://wiki.rubyworks.github.com/raml" end
We get a two layer hash.
data = RAML.read(@text) data[:resources][:home].assert == "http://rubyworks.github.com/raml" data[:resources][:docs].assert == "http://rubyworks.github.com/raml/docs/api" data[:resources][:wiki].assert == "http://wiki.rubyworks.github.com/raml"
RAML is also considers the content of a block. If it is a scalar entry, such as a String, then that will be assigned to the key.
Given a RAML document:
description %{ This is a description. It can have multiple lines. RAML handles this just fine, because Ruby does too. }
Loading this document, description will contain the text as expected.
data = RAML.read(@text) text = data[:description].sub(/\s+/, ' ').strip text.assert.start_with?("This is") text.assert.end_with?("does too.")
It is only unfortunate that Ruby doesn’t have a margin controlled string notation (e.g. `%L{ }`) so that post processing with `sub()` would not be neccessary.
RAML has some options that makes it more flexible than many other data lanaguages. For instance, it can allow for multi-key entries.
Given a RAML document:
source "http://rubygems.org" gem "facets", "~> 2.8" gem "ansi", "~> 1.1"
We simply need to inform the reader to allow identical keys.
data = RAML.read(@text, :multikey=>true) data.assert == { :source=>"http://rubygems.org", :gem=>[["facets", "~> 2.8"],["ansi", "~> 1.1"]] }
If we did not turn on the multi-key option, then the last `gem` entry would have simply overwritten the former.
data = RAML.read(@text) data.assert == { :source=>"http://rubygems.org", :gem=>["ansi", "~> 1.1"] }
Not let’s show-off the benefit of using RAML.read instead of RAML.eval.
Given a RAML document:
sum "word".upcase
We will see that the result of calling `#upcase` CANNOT be evaluated and will raise an error.
expect Exception do data = RAML.read(@text) end if RUBY_VERSION >= '1.9'
Note, this last assertion is only true for Ruby 1.9+, becuase Ripper is not supported by older versions of Ruby.