refactor internals, get rid of YAML anchors while still allowing to be lazy

This commit is contained in:
Georg Gadinger 2023-01-31 22:57:44 +01:00
parent c826d9d2c8
commit 4f7d74606c
2 changed files with 52 additions and 70 deletions

View File

@ -1,86 +1,73 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'yaml' require "yaml"
# Generates some questions. # Generates some questions.
module QuestionGenerator module QuestionGenerator
# Version of QuestionGenerator # Version of QuestionGenerator
VERSION = "1.0.0" VERSION = "1.1.0"
class << self class << self
# The base path to the questions (e.g. +'/home/nilsding/questions'+). # The base path to the questions (e.g. +'/home/nilsding/questions'+).
attr_accessor :question_base_path attr_reader :question_base_path
# The default locale, as a symbol. # The default locale, as a symbol.
attr_accessor :default_locale attr_accessor :default_locale
end end
module_function
# Generates a new question. # Generates a new question.
# @param options [Hash] A customizable set of options. # @param options [Hash] A customizable set of options.
# @option options [Symbol] :locale (@default_locale) The target locale # @param :locale [Symbol] The target locale
# @option options [String] :prefix Prefix of the question, e.g. +'¿'+ # @param :prefix [String] Prefix of the question, e.g. +'¿'+
# @option options [String] :suffix ('?') Suffix of the question, e.g. +' ?'+ # @param :suffix [String] Suffix of the question, e.g. +' ?'+
# @option options [Boolean] :use_compiled (true) Use compiled questions
# instead of generating it. See also {compile}
# @return [String] String containing the generated question. # @return [String] String containing the generated question.
def self.generate(options = {}) def generate(locale: @default_locale, prefix: "", suffix: "?")
opts = { compile(locale:) unless @compiled.key?(locale)
locale: @default_locale,
prefix: '', prefix + @compiled[locale].sample + suffix
suffix: '?',
use_compiled: true
}.merge!(options)
if opts[:use_compiled] and !@compiled[opts[:locale]].nil?
opts[:prefix] + @compiled[opts[:locale]].sample + opts[:suffix]
else
questions = YAML.load_file(File.expand_path("#{opts[:locale].to_s}.yml", @question_base_path))
opts[:prefix] + get_question(questions).strip + opts[:suffix]
end
end end
# Compiles all the questions and stores it into the +@compiled+ hash. # Compiles all the questions and stores it into the +@compiled+ hash.
# @param options [Hash] A customizable set of options. # @param :locale [Symbol] The target locale
# @option options [Symbol] :locale (@default_locale) The target locale def compile(locale: @default_locale)
def self.compile(options = {}) questions = YAML.load_file(File.expand_path("#{locale}.yml", @question_base_path))
opts = { @compiled[locale] = build(questions)
locale: @default_locale end
}.merge!(options)
questions = YAML.load_file(File.expand_path("#{opts[:locale].to_s}.yml", @question_base_path)) def question_base_path=(path)
@compiled[@default_locale] = build(questions) raise Errno::ENOENT.new(path) unless Dir.exist?(path)
@compiled = {} # new dir, force a recompile
@question_base_path = path
end end
private private
def self.get_question questions module_function
question = ""
if questions.is_a? Hash def build(questions, q = "")
key = questions.keys.sample ary = []
value = questions[key]
question = "#{key} #{get_question(value)}" case questions
elsif questions.is_a? Array when Hash
question = get_question questions.sample questions.each do |k, v|
elsif questions.is_a? String Array(k).each do |variant|
question = questions ary << build(v, "#{q}#{variant} ")
end
question
end
def self.build(questions, q = "")
ary = []
if questions.is_a? Hash
questions.each do |k, v|
ary << build(v, "#{q}#{k} ")
end end
elsif questions.is_a? Array
questions.each do |v|
ary << build(v, q)
end
elsif questions.is_a? String
return "#{q}#{questions}".strip
end end
ary.flatten when Array
questions.each do |v|
ary << build(v, q)
end
when String
return "#{q}#{questions}".strip
end end
@question_base_path = File.expand_path("../questions/", __FILE__) ary.flatten
@default_locale = :en end
@compiled = {}
@question_base_path = File.expand_path("./questions/", __dir__)
@default_locale = :en
@compiled = {}
end end

View File

@ -47,17 +47,14 @@ Do:
- muffins - muffins
- video games - video games
know: know:
too: [much, too much]:
much: about:
about: &friends_know_much
- your: - your:
- life - life
- hobbies - hobbies
- family - family
- friends - friends
- you - you
much:
about: *friends_know_much
What: What:
- was: - was:
the: the:
@ -118,11 +115,10 @@ What:
- foxes - foxes
- dogs - dogs
- lizards - lizards
- activity: &activity - [activity, activities]:
do: do:
you: you:
- enjoy the most - enjoy the most
- activities: *activity
- kind: - kind:
of: of:
animals: animals:
@ -133,7 +129,7 @@ What:
really: really:
find: find:
cute: cute:
- in a person? - in a person
- is: - is:
your: your:
- first memory - first memory
@ -169,7 +165,7 @@ What:
- Facebook - Facebook
- YouTube - YouTube
the: the:
best: &is_the_best [best, worst]:
thing: thing:
- about: - about:
the: the:
@ -188,7 +184,6 @@ What:
fast: fast:
food: food:
- chain - chain
worst: *is_the_best
one: one:
- thing you would like to become better at - thing you would like to become better at
- was: - was:
@ -199,10 +194,9 @@ What:
- did - did
- ate - ate
- looked for - looked for
best: &was_the_best [best, worst]:
thing: thing:
- "you've eaten so far" - "you've eaten so far"
worst: *was_the_best
- languages do you know - languages do you know
- apps do you use daily - apps do you use daily
- 'is heavier: a kilogram of steel, or a kilogram of feathers' - 'is heavier: a kilogram of steel, or a kilogram of feathers'
@ -219,6 +213,7 @@ Can:
- piano - piano
- guitar - guitar
- trumpet - trumpet
- saxophone
- baseball - baseball
- ski - ski
- cook - cook