Top Level Namespace

Instance Method Summary collapse

Instance Method Details

#SRSLY?(*args) ⇒ Object

Prompt user for an input.

Parameters:

  • message (String)

    Output message

  • options (Hash)

    Options

Returns:

  • (Object)

Raises:

  • (ArgumentError)


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/srsly.rb', line 9

def SRSLY? *args
  message, options =
    case args.length
    when 0
      [nil, {}]
    when 1
      case args.first
      when Hash
        [nil, args.first]
      when String
        [args.first, {}]
      else
        raise ArgumentError, "Invalid parameter"
      end
    when 2
      args
    else
      raise ArgumentError, "wrong number of arguments (#{args.length} for 2)"
    end

  message ||= 'Are you sure (Y/N)? '
  options = {
    :error => nil,
    :tries => nil,
    :in    => $stdin,
    :out   => $stdout
  }.merge(options)

  error, tries, input, output = options.values_at(
    :error, :tries, :in, :out)

  raise ArgumentError, "Message must be a String" unless message.is_a?(String)
  raise ArgumentError, "Invalid :tries" unless tries.nil? ||
                                               (tries.is_a?(Fixnum) && tries > 0)

  read =
    if input.respond_to?(:gets)
      proc { input.gets }
    elsif input.is_a?(Proc)
      input
    else
      raise ArgumentError, "Invalid :in"
    end

  write =
    if output.respond_to?(:write)
      proc { |s| output.write s }
    elsif output.is_a?(Proc)
      output
    else
      raise ArgumentError, "Invalid :out"
    end

  alert =
    case error
    when String
      proc { write.call error }
    when Proc
      error
    else
      raise ArgumentError, "Invalid :error"
    end if error

  resps = options.select { |k, v| k.is_a?(Regexp) || k.is_a?(String) || k.nil? }
  resps = Hash[resps].merge(
    # Default responses if nothing given
    /^y/i => true,
    /^n/i => false) if resps.reject { |k, _| k.nil? }.empty?

  ask = proc { write.call message }
  t   = 0
  got = nil
  while tries.nil? || t < tries
    ask.call got, t += 1, tries

    if got = read.call
      got = got.chomp
    else
      write.call $/
    end

    resps.each do |k, v|
      case k
      when String, nil
        return v if k == got
      when Regexp
        return v if k.match got
      end
    end

    ask = alert if alert
  end

  nil
end