Class: Clack::Group

Inherits:
Object
  • Object
show all
Defined in:
lib/clack/group.rb

Overview

Collects results from multiple prompts and handles cancellation gracefully.

Examples:

Basic usage

result = Clack.group do |g|
  g.prompt(:name) { Clack.text(message: "Your name?") }
  g.prompt(:age) { Clack.text(message: "Your age?") }
end
# => { name: "Alice", age: "30" } or Clack::CANCEL

With previous results

result = Clack.group do |g|
  g.prompt(:name) { Clack.text(message: "Your name?") }
  g.prompt(:greeting) { |r| Clack.text(message: "Hello #{r[:name]}!") }
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(on_cancel: nil) ⇒ Group

Returns a new instance of Group.



23
24
25
26
27
# File 'lib/clack/group.rb', line 23

def initialize(on_cancel: nil)
  @results = {}
  @prompts = []
  @on_cancel = on_cancel
end

Instance Attribute Details

#resultsHash (readonly)

Returns The collected results.

Returns:

  • (Hash)

    The collected results



21
22
23
# File 'lib/clack/group.rb', line 21

def results
  @results
end

Instance Method Details

#prompt(name) {|results| ... } ⇒ void

This method returns an undefined value.

Define a prompt in the group.

Parameters:

  • name (Symbol, String)

    The key for this result

Yields:

  • (results)

    Block that returns a prompt result

Yield Parameters:

  • results (Hash)

    Previous results collected so far

Raises:

  • (ArgumentError)


35
36
37
38
39
# File 'lib/clack/group.rb', line 35

def prompt(name, &block)
  raise ArgumentError, "Block required for prompt :#{name}" unless block_given?

  @prompts << {name: name.to_sym, block: block}
end

#runHash, Clack::CANCEL

Run all prompts and collect results.

Returns:

  • (Hash, Clack::CANCEL)

    Results hash or CANCEL if user cancelled



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/clack/group.rb', line 44

def run
  @prompts.each do |prompt_def|
    name = prompt_def[:name]
    block = prompt_def[:block]

    # Pass previous results to the block if it accepts an argument
    result = if block.arity.zero?
      block.call
    else
      block.call(@results.dup.freeze)
    end

    if Clack.cancel?(result)
      @results[name] = :cancelled
      @on_cancel&.call(@results.dup.freeze)
      return CANCEL
    end

    @results[name] = result
  end

  @results
end