class BBS::Flow
A line-mode script for a caller: a list of steps that BBS::FlowRunner runs in order on the session. Each DSL method below appends one step (a Flow::Steps object); nothing is written to the caller while the flow is defined.
Steps share a context Hash that holds :session_id and the answers of ask. A step that reads a line ends the flow when the caller hangs up. Most boards use a Flow as glue only: a call step that runs the board’s own screen, then another for the goodbye.
FLOW = BBS::Flow.define do screen :welcome ask :name, prompt: 'Your name', transform: :upcase, validate: :non_empty say 'Nice to meet you.' menu 'Choose:', loop: true do option('Who am I') { text { |ctx| ctx[:name] } } option('Leave') { exit_menu } end end
Attributes
The steps, an Array of Flow::Steps objects, and the folder the screen steps read from (or nil).
The steps, an Array of Flow::Steps objects, and the folder the screen steps read from (or nil).
Public Class Methods
Source
# File lib/bbs/flow.rb, line 36 def self.define(screens_dir: nil, &) flow = new(screens_dir: screens_dir) flow.instance_eval(&) flow.freeze end
Builds a flow by evaluating the block in a new Flow, and returns it frozen.
screens_dir is where this flow’s screen steps find their ERB files; without it they use BBS.config.screens_dir. A flow that ships with its own screens (a door from a gem) names its folder here.
Source
# File lib/bbs/flow.rb, line 53 def initialize(screens_dir: nil) @steps = [] @screens_dir = screens_dir end
Creates an empty flow. Flow.define is the usual way to build one.
Public Instance Methods
Source
# File lib/bbs/flow.rb, line 121 def app(definition) = add(Steps::App.new(definition))
Runs the windowed BBS::Application definition on the session.
# File lib/bbs/flow.rb, line 84 def ask(name, prompt:, transform: nil, validate: nil) add(Steps::Ask.new(name, prompt, transform, validate)) end
Prints prompt, reads a line, and stores it stripped in the context under name.
- transform
-
:upcase,:downcase, or a Proc applied to the answer - validate
-
:email,:non_empty, or a Proc or Method that returns truthy for a good answer; a bad answer prints an error and ends the flow
Source
# File lib/bbs/flow.rb, line 118 def call(&block) = add(Steps::Call.new(block))
Calls the block with the context and the BBS::FlowRunner. Returning :halt ends the flow; an error is logged and shown to the caller, and the flow goes on.
# File lib/bbs/flow.rb, line 103 def confirm(message, denied: nil, &) = add(Steps::Confirm.new(message, denied, block_given? ? Flow.steps(&) : nil))
Asks message with a [yes/no] prompt. With a block, the steps defined in the block run on yes and the flow goes on either way. Without a block, the flow goes on only on yes. On no, denied is written when given.
Source
# File lib/bbs/flow.rb, line 97 def gate(denied:, &check) = add(Steps::Gate.new(check, denied))
Calls the block with the context; when it returns falsy, writes denied and ends the flow.
# File lib/bbs/flow.rb, line 93 def pause(message, seconds: 1.0) = add(Steps::Pause.new(message, seconds))
Writes message and sleeps for seconds.
Source
# File lib/bbs/flow.rb, line 90 def persist(*fields, store:) = add(Steps::Persist.new(fields.flatten, store))
Saves the context values of fields (those present) to store, a BBS::Store, in the row of the session id.
Source
# File lib/bbs/flow.rb, line 71 def say(text, style: :muted) = add(Steps::Say.new(text, style))
Writes text as an indented paragraph with a blank line around it.
Source
# File lib/bbs/flow.rb, line 61 def screen(name, **vars) = add(Steps::Screen.new(name, vars))
Renders the ERB screen name from the screens folder and writes it. The template sees the context plus vars; a Symbol value in vars is looked up in the context.
# File lib/bbs/flow.rb, line 75 def text(content = nil, style: :muted, &block) = add(Steps::Text.new(content, block, style))
Writes one indented line: content, or the block’s return value (called with the context). Nothing is written for nil.