Module: Commander::UI::AskForClass

Included in:
Methods
Defined in:
lib/commander/user_interaction.rb

Overview

Implements ask_for_CLASS methods, e.g. ask_for_float, ask_for_date, or ask_for_pathname: each prompts the user via HighLine and parses the response as the requested class. Common classes (Float, Integer, String, Symbol, Regexp, Array, File, Pathname) get explicit methods defined below; any other class that responds to .parse (Date, Time, URI, ...) is resolved dynamically by #method_missing.

Constant Summary collapse

DEPRECATED_CONSTANTS =

Constants that are either deprecated (and would warn when read via Object.const_get) or simply not meant to be treated as ask_for_* targets; skipped while scanning Object.constants in #method_missing.

%i[Config TimeoutError MissingSourceFile NIL TRUE FALSE Fixnum Bignum Data ScanError SortedSet].freeze

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *arguments) ⇒ Object

Handles ask_for_* calls not covered by one of the explicitly defined methods above, by searching for a same-named top-level class that implements .parse and asking HighLine to parse the response as that class. Falls through to super (and so ultimately raises NoMethodError) for unrecognized method names or unrecognized classes.



323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/commander/user_interaction.rb', line 323

def method_missing(method_name, *arguments, &)
  if method_name.to_s =~ /^ask_for_(.*)/
    if arguments.count != 1
      fail ArgumentError, "wrong number of arguments (given #{arguments.count}, expected 1)"
    end

    prompt = arguments.first
    requested_class = Regexp.last_match[1]

    # All Classes that respond to #parse
    # Ignore constants that trigger deprecation warnings
    available_classes = (Object.constants - DEPRECATED_CONSTANTS).map do |const|
      Object.const_get(const)
    end.select do |const|
      const.instance_of?(Class) && const.respond_to?(:parse)
    end

    klass = available_classes.find { |k| k.to_s.downcase == requested_class }
    if klass
      HighLine.default_instance.ask(prompt, klass)
    else
      super
    end
  else
    super
  end
end

Instance Method Details

#respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


351
352
353
# File 'lib/commander/user_interaction.rb', line 351

def respond_to_missing?(method_name, include_private = false)
  method_name.to_s.start_with?('ask_for_') || super
end