HighLine:ask の挙動、中身
以下のように引数は、Question に引き渡される
def ask( question, answer_type = String, &details ) # :yields: question @question ||= Question.new(question, answer_type, &details)
gather への挙動
>> require "highline/import" => true >> ask("foo?") { |q| q.gather = true } => [] >> ask("foo?") { |q| q.gather = true } foo? aaa => "aaa"
は、
class HighLine ... def ask( question, answer_type = String, &details ) # :yields: question @question ||= Question.new(question, answer_type, &details) return gather if @question.gather ... def gather( ) ... @answers = [ ] ... @question.gather = false ... @answers end
から理解できた。
- ask が呼ばれ Question.new, @question.gather は true に設定
- gather が呼ばれ、@question.gather は false に設定、返り値は @answers に設定された []
- ask が呼ばれ @question は既にあるので、Question.new は呼ばれず、@question.gather も true に設定されない
- 「return gather if @question.gather」以降の通常のコードが実行される
全体の構造
- Question.new
- gather の処理
- say
- begin 〜 end で囲われた中で入力の判定。ダメな場合は例外を発生させ rescue して retry
- gather で return しない場合以外は、ensure で @question = nil と reset
多少の疑問
def ask( question, answer_type = String, &details ) # :yields: question ... begin @answer = @question.answer_or_default(get_response) unless @question.valid_answer?(@answer) explain_error(:not_valid) raise QuestionError end
なら、次の記述
if @question.in_range?(@answer) ... else explain_error(:not_in_range) raise QuestionError end
はそう書かず、
unless @question.in_range?(@answer) explain_error(:not_in_range) raise QuestionError end ...
でも良さそうな?
「if @question.in_range?(@answer)」内の @question.confirm まわりの処理が良く分からないや〜