Module: MadderLib::Conditional::Recur::Phrase

Included in:
AnytimePhrase
Defined in:
lib/madderlib/conditional/recur.rb

Overview

Recur::Phrase

Introduces support for recurrant usage of a Phrase. This is particularly useful for an AnywherePhrase, whose position is randomly chosen. If it has a recurrence, it may appear multiple times. All of this is independent of whatever Instructions are contained within the Phrase

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(target) ⇒ Object

:nodoc:



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
# File 'lib/madderlib/conditional/recur.rb', line 15

def self.included(target) #:nodoc:
	#	before each run, we need to prepare ourself
	target.add_prepare do |phrase, context|
		unless phrase.conditional_recur_tester
			#	we'll only run once if not told otherwise
			phrase.recur 1
		end

		#	we must retain state (the number of times called)
		#	and a consistent block for testing
		state = context.state(phrase)
		state[:recur_block] = phrase.conditional_recur_tester.block
		state[:recur_count] = 0
	end

	#	register a test for recurrance
	target.add_test do |phrase, context|
		#	where we at now
		state = context.state(phrase)
		block = state[:recur_block]
		count = state[:recur_count]
		state[:recur_count] = count + 1

		#	the block call returns the result of our test
		#		we buffered the block, but want to invoke it conveniently
		phrase.conditional_recur_tester.invoke(count, context, &block)
	end
end

Instance Method Details

#conditional_recur_testerObject

:nodoc:



86
87
88
# File 'lib/madderlib/conditional/recur.rb', line 86

def conditional_recur_tester #:nodoc:
	@recur_tester
end

#recur(*args, &block) ⇒ Object Also known as: recurs, recurring

Specifies the recurrance of this Phrase

If provided, the arguments should contain:

  • a numeric value, which becomes the count

  • a Range, or two numerics (which define a Range), from which the count is chosen randomly

  • a Proc / lambda / block / closure, which returns false when the recurrance should stop. \

The block can either take (a) no arguments, (b) the recurrance count, or; © the count and a Context.

A recurrance count of 0 will exclude the Phrase from the Builder result

A recurrance always ends when any Instruction returns an empty set of words. Processing will skip to the next Phrase, even if more recurrances are available

Examples:

builder = madderlib do
  say(:start)
  say(:end)
  anytime.recurring(2).say(:any)
  anytime.recurring {|count| count < 2 }.say(:also)
end

words = builder.words
words.find_all {|word| word == 'any' }.should have(2).items
words.find_all {|word| word == 'also' }.should have(2).items


70
71
72
73
74
# File 'lib/madderlib/conditional/recur.rb', line 70

def recur(*args, &block)
	#	build a tester, set it aside
	@recur_tester = Helper::TestBlock.new *args, &block
	self
end

#recurs?(context = MadderLib::Context::EMPTY) ⇒ Boolean

Returns true if the Phrase can recur. By default, the recurrance count is 1, in which case this method returns false

Returns:

  • (Boolean)


80
81
82
# File 'lib/madderlib/conditional/recur.rb', line 80

def recurs?(context=MadderLib::Context::EMPTY)
	!! (conditional_recur_tester && (conditional_recur_tester.to_i(context) > 1))
end