class Spirit::Render::Problem
Renders a single problem. This class doesn't do anything useful; use the child classes (e.g. {Spirit::Render::Multi}) instead. Child classes should override {#valid?}.
Constants
- ANSWER
Required key in YAML markup. Value contains answers.
- FORMAT
Required key in YAML markup. Value indicates type of problem.
- ID
Generated
ID
.- KEYS
Required keys.
- QUESTION
Required key in YAML markup. Value contains question body.
Attributes
Public Class Methods
Dynamically creates accessor methods for YAML values. @example
accessor :id
# File lib/spirit/render/templates/problem.rb, line 50 def accessor(*args) args.each { |arg| define_method(arg) { @yaml[arg] } } end
@return [Problem] problem
# File lib/spirit/render/templates/problem.rb, line 55 def get_instance(hash, digest) raise RenderError, "Missing 'format' key in given YAML" unless instantiable? hash klass = Spirit::Render.const_get(hash[FORMAT].capitalize) raise NameError unless klass < Problem klass.new(hash, digest) rescue NameError raise RenderError, 'Unrecognized format: %p' % hash[FORMAT] end
Creates a new problem from the given YAML. @param [Hash] yaml parsed yaml object @param [String] digest SHA-256 hash of yaml text @param [Fixnum] id integer ID
of question
# File lib/spirit/render/templates/problem.rb, line 80 def initialize(yaml, digest) @yaml, @digest, @nesting, @id = yaml, digest, [], 0 raise RenderError.new('Invalid problem.') unless @yaml[QUESTION].is_a? String @yaml[QUESTION] = markdown.render @yaml[QUESTION] end
Parses the given text for questions and answers. If the given text does not contain valid YAML or does not contain the format key, raises an {Spirit::Render::RenderError}. @param [String] text embedded yaml @return [Problem] problem
# File lib/spirit/render/templates/problem.rb, line 39 def parse(text) digest = OpenSSL::Digest::SHA256.digest text yaml = YAML.load text get_instance(yaml, digest) rescue ::Psych::SyntaxError => e raise RenderError, e.message end
Private Class Methods
# File lib/spirit/render/templates/problem.rb, line 66 def instantiable?(hash) hash.is_a?(Hash) and hash.has_key?(FORMAT) end
Public Instance Methods
Retrieves the answer from the given YAML object in a serializable form. @see serializable @return [String, Numeric, TrueClass, FalseClass] answer
# File lib/spirit/render/templates/problem.rb, line 96 def answer serialize @yaml[ANSWER] end
@todo TODO should probably show some error message in the preview,
so that the author doesn't have to read the logs.
# File lib/spirit/render/templates/problem.rb, line 88 def render(locals={}) raise RenderError.new('Invalid problem.') unless valid? super @yaml.merge(locals) end
Private Instance Methods
If obj
is one of String, Numeric, true
, or false
, the it's returned. Otherwise, to_s
is invoked on the object and returned. @return [String, Numeric, TrueClass, FalseClass] answer
# File lib/spirit/render/templates/problem.rb, line 105 def serialize(obj) case obj when String, Numeric, TrueClass, FalseClass then obj else obj.to_s end end
Checks that all required {KEYS} exist in the YAML, and that the question is given as a string. @return [Boolean] true iff the parsed yaml contains a valid problem.
# File lib/spirit/render/templates/problem.rb, line 114 def valid? KEYS.all? { |key| @yaml.has_key? key } and question.is_a? String end