Class: MethodInvocationQuestion

Inherits:
FollowUpQuestion show all
Defined in:
lib/battleroom/models/method_invocation_question.rb

Instance Attribute Summary collapse

Attributes inherited from FollowUpQuestion

#original_question

Attributes inherited from Question

#answer_value, #data, #data_structure, #data_structure_class, #evaluation_scope, #explanation, #input_mechanism, #user_input, #variable_name, #variable_value

Instance Method Summary collapse

Methods inherited from FollowUpQuestion

#initialize

Methods inherited from Question

#congratulation_sequence, #enter_evaluation_loop, generate_question, #get_input, #handle_syntax_error_exceptions, #initialize

Constructor Details

This class inherits a constructor from FollowUpQuestion

Instance Attribute Details

#desired_answer_class_formattedObject (readonly)

Returns the value of attribute desired_answer_class_formatted.



5
6
7
# File 'lib/battleroom/models/method_invocation_question.rb', line 5

def desired_answer_class_formatted
  @desired_answer_class_formatted
end

#desired_answer_formattedObject (readonly)

Returns the value of attribute desired_answer_formatted.



5
6
7
# File 'lib/battleroom/models/method_invocation_question.rb', line 5

def desired_answer_formatted
  @desired_answer_formatted
end

Instance Method Details

#evaluate_user_inputObject



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/battleroom/models/method_invocation_question.rb', line 70

def evaluate_user_input
  enter_evaluation_loop do |user_submission|
    begin
      return_from_eval = original_question.evaluation_scope.eval(user_submission)
      if return_from_eval == original_question.eval_answer
        true
      else
        print_incorrect_input_prompt(return_from_eval)
      end
    rescue NoMethodError => e
      print_no_method_error_prompt
    rescue NameError => e
      print_name_error_prompt(e, user_submission)
    rescue ArgumentError => e
      print_argument_error_prompt(e)
    end
  end
end

#format_method_definition_for_stdoutObject



14
15
16
17
18
# File 'lib/battleroom/models/method_invocation_question.rb', line 14

def format_method_definition_for_stdout
  code = CodeRay.scan($input, :ruby)
  ansi_prepped_string = code.term
  indent_all_lines_for_stdout(ansi_prepped_string)
end

#isolate_argument_names_from_method_defObject



57
58
59
# File 'lib/battleroom/models/method_invocation_question.rb', line 57

def isolate_argument_names_from_method_def
  isolate_parameter_list_string_from_method_def.scan(/([^,\s]+)+/x).flatten
end

#isolate_parameter_list_string_from_method_defObject



61
62
63
64
# File 'lib/battleroom/models/method_invocation_question.rb', line 61

def isolate_parameter_list_string_from_method_def
  original_question.user_answer_verified.match /\((.+)\)/
  $1
end

#isolate_variable_name_from_name_error(error) ⇒ Object



44
45
46
# File 'lib/battleroom/models/method_invocation_question.rb', line 44

def isolate_variable_name_from_name_error(error)
  error.name.to_s
end

#post_initializeObject



7
8
9
10
11
12
# File 'lib/battleroom/models/method_invocation_question.rb', line 7

def post_initialize
  @desired_answer_formatted = format_value_for_stdout_and_eval(original_question.eval_answer)
  @desired_answer_class_formatted = format_class_for_output(original_question.eval_answer.class)
  print_method_invocation_prompt
  evaluate_user_input
end


48
49
50
51
52
53
54
55
# File 'lib/battleroom/models/method_invocation_question.rb', line 48

def print_argument_error_prompt(e)
  e.message.match(/wrong number of arguments \((\d) for (\d)\)/)
  passed_arg_count = $1.to_i
  expected_arg_count = $2.to_i
  battleprint "You just triggered a common Ruby error that reads:\n".red
  battleprint "\tArgumentError: #{e.message}\n".green
  battleprint "Basically, you defined the '#{original_question.method_name}' method to expect #{expected_arg_count} argument(s), and you're only passing it #{passed_arg_count}. Try again.\n".red
end


66
67
68
# File 'lib/battleroom/models/method_invocation_question.rb', line 66

def print_incorrect_input_prompt(return_from_eval)
  battleprint "Your code returned the #{format_class_for_output(return_from_eval.class)} value #{return_from_eval.to_s} when it should have returned the #{desired_answer_class_formatted} value #{desired_answer_formatted}. Try again.".red
end


20
21
22
23
24
# File 'lib/battleroom/models/method_invocation_question.rb', line 20

def print_method_invocation_prompt
  battleprint "You now have the method defined below at your disposal.\n".blue
  battleprint format_method_definition_for_stdout
  battleprint "\nInvoke the '#{original_question.method_name}' method such that it returns the ".blue + desired_answer_class_formatted.blue + " value ".blue + desired_answer_formatted.yellow + ".\n".blue
end


32
33
34
35
36
37
38
39
40
41
42
# File 'lib/battleroom/models/method_invocation_question.rb', line 32

def print_name_error_prompt(error, user_submission)
  battleprint "\nYou just triggered a common Ruby error that reads:\n".red
  battleprint "\tNameError: #{error.message}\n".green
  referenced_variable = isolate_variable_name_from_name_error(error)
  parameters = isolate_argument_names_from_method_def
  if parameters.find { |parameter| parameter == referenced_variable }
    battleprint "Looks like the variable you referenced was one of the argument names in your method #{'definition'.red.underline}. The arguments in method definitions are just placeholders for whatever values end up getting passed in when the method is called. Think on this for a moment before trying again.\n".red
  else
    battleprint "Basically, you're referencing a variable, \"#{referenced_variable}\", that hasn't been assigned a value.\n".red
  end
end


26
27
28
29
30
# File 'lib/battleroom/models/method_invocation_question.rb', line 26

def print_no_method_error_prompt
  battleprint "\nYou just trigged a common Ruby error that reads: \n".red
  battleprint "\tundefined local variable or method \'WHATEVER_METHOD_YOU_TRIED_TO_INVOKE\'\n".green
  battleprint "Basically, you tried to invoke a method that doesn't exist. Try again.\n".red
end