Module: MadderLib::Conditional::Allowed::Instruction

Included in:
Instruction
Defined in:
lib/madderlib/conditional/allowed.rb

Overview

Allowed::Instruction

Introduces support for conditional usage of an Instruction

The conditional logic is evaluated for each separate execution of the Builder. If the conditional returns false, then the Instruction is excluded from use. If it returns true, then the Instruction is still a viable candidate (though other constraints may be applied)

See: Allowed::Phrase

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(target) ⇒ Object

:nodoc:



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/madderlib/conditional/allowed.rb', line 46

def self.included(target) #:nodoc:
	#	register a test to test all allowances for the instruction
	#		return false at the first one that fails
	target.add_test do |instruction, context|
		failure = instruction.conditional_allowances.find do |block|
			#	first failure stops us
			(! Context.invoke(block, context))
		end

		failure.nil?
	end
end

Instance Method Details

#assuming(id = nil, &block) ⇒ Object Also known as: presuming, if

The instruction will only be used if these conditions are true

The id of a Phrase can be provided. If so, then the condition tested is: the reference must have already been added to the Builder’s result. This can be identified through Context#spoken

Alternately, a custom block can be provided. The block can either take no arguments, or a Context. The Instruction may only be used when that block returns a true (eg. non-false) value

Examples:

switch = false
builder = madderlib do
  an(:on).says('on').assuming { switch }
  an(:off).says('off').if { ! switch }
  say('bright').if :on
  say('dark').if :off
end

builder.sentence.should eql('off dark')
switch = true
builder.sentence.should eql('on bright')


83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/madderlib/conditional/allowed.rb', line 83

def assuming(id=nil, &block)
	if block
		raise Error, 'block AND id provided, requires one or the other' if id
		Context.validate(block)
	else
		#	true if the id expressed has been spoken
		block = lambda {|context| context.spoken_ids.include?(id) }
	end

	#	set it aside for a lazy day
	conditional_allowances << block
	self
end

#conditional_allowancesObject

:nodoc:



137
138
139
# File 'lib/madderlib/conditional/allowed.rb', line 137

def conditional_allowances #:nodoc:
	@conditional_allowances ||= []
end

#forbidding(id = nil, &block) ⇒ Object Also known as: unless

The instruction will only be used if these conditions are false. This is the logical opposite of assuming.

The id of a Phrase can be provided. If so, then the condition tested is: the reference must not have been added to the Builder’s result. This can be identified through Context#spoken

Alternately, a custom block can be provided. The block can either take no arguments, or a Context. The Instruction may only be used when that block returns a false value

Examples:

switch = false
builder = madderlib do
  an(:on).says('on').forbidding { ! switch }
  an(:off).says('off').unless { switch }
  say('bright').unless :off
  say('dark').unless :on
end

builder.sentence.should eql('off dark')
switch = true
builder.sentence.should eql('on bright')


122
123
124
125
126
127
128
129
130
131
132
# File 'lib/madderlib/conditional/allowed.rb', line 122

def forbidding(id=nil, &block)
	if block
		raise Error, 'block AND id provided, requires one or the other' if id
		Context.validate(block)

		self.assuming {|context| ! Context.invoke(block, context) }
	else
		#	true unless the id expressed has been spoken
		self.assuming {|context| ! context.spoken_ids.include?(id) }
	end
end