Class: MadderLib::Instruction
- Inherits:
-
Object
- Object
- MadderLib::Instruction
- Extended by:
- Conditional::Registry::Static
- Includes:
- Conditional::Allowed::Instruction, Conditional::Likely::Instruction, Conditional::Registry::Instance, Conditional::Repeat::Instruction
- Defined in:
- lib/madderlib/instruction.rb
Overview
Instruction
A specific instruction within a MadderLib ruleset.
A Phrase is comprised of one or more Instructions. Each Instruction contains the logic necessary to produce the result for the Phrase
Typical ‘words’ that can appear in an Instruction are:
-
a String
-
a Symbol
-
a Proc / lambda / block / closure
-
another Builder
-
an Array of the above
The logic by which these Object types are resolved is described within wordify .
An Instruction also supports:
-
repetition, via Conditional::Repeat
-
conditional usage, via Conditional::Allowed
-
proportionate usage, via Conditional::Likely
Instance Attribute Summary collapse
-
#phrase ⇒ Object
readonly
A refererence to the Phrase which contains this Instruction.
-
#words ⇒ Object
readonly
An Array of the words produced by this Instruction.
Class Method Summary collapse
-
.wordify(source, context) ⇒ Object
Converts the object passed into a ‘word’, according to the following rules:.
Instance Method Summary collapse
-
#alternately(*args, &block) ⇒ Object
(also: #or)
A proxy for phrase.alternately .
-
#initialize(phrase, *args, &block) ⇒ Instruction
constructor
Constructs a new Instruction.
-
#speak(context) ⇒ Object
Generates the list of words for this Instruction.
Methods included from Conditional::Registry::Static
add_prepare, add_test, conditional_prepares, conditional_tests
Methods included from Conditional::Likely::Instruction
#conditional_likely_tester, included, #likely
Methods included from Conditional::Repeat::Instruction
included, #repeat, #repeat_speak, #times, #while
Methods included from Conditional::Allowed::Instruction
#assuming, #conditional_allowances, #forbidding, included
Methods included from Conditional::Registry::Instance
Constructor Details
#initialize(phrase, *args, &block) ⇒ Instruction
Constructs a new Instruction
The containing Phrase is required.
Any number of arguments may be provided, and they become the Instruction’s words. An optional block can be provided, and if so, it is also treated as a word (since a Proc is considered a valid ‘word’)
43 44 45 46 47 |
# File 'lib/madderlib/instruction.rb', line 43 def initialize(phrase, *args, &block) @phrase = phrase @words = args @words << block if block_given? end |
Instance Attribute Details
#phrase ⇒ Object (readonly)
A refererence to the Phrase which contains this Instruction
30 31 32 |
# File 'lib/madderlib/instruction.rb', line 30 def phrase @phrase end |
#words ⇒ Object (readonly)
An Array of the words produced by this Instruction. The term ‘word’ is used very loosely here; they are simply the Objects provided during construction
33 34 35 |
# File 'lib/madderlib/instruction.rb', line 33 def words @words end |
Class Method Details
.wordify(source, context) ⇒ Object
Converts the object passed into a ‘word’, according to the following rules:
-
nil
=> nil -
String
=> itself (blank Strings also) -
Proc / lambda / block / closure
=> the result of invoking the block. \
The block can either take no arguments, or a Context. \ Please note that resolution of the Proc’s scoped variables (etc.) occurs only at the time that wordify is invoked!
-
Builder
=> the result of Builder#words, which will be an Array -
Array
=> a flattened Array of the each element, as converted via wordify
Anything other Object type is converted to a string via Object#to_s.
See: speak
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/madderlib/instruction.rb', line 132 def wordify(source, context) # our own dogfood if Builder === source # build the words # pull back and track the context # we know they'll be Strings, so no need for recursion return source.words {|sub_context| context.add_context sub_context } end while (Proc === source) # evaluate, then wordify the result # this addresses the Proc-returns-a-Proc condition # it's a corner case source = Context.invoke(source, context) end if (Array === source) # recursive parsing # plus flattening! source = source.inject([]) do |a, word| word = wordify(word, context) if Array === word a += word else a << word end a end elsif source && ! (String === source) # don't stringify nil source = source.to_s end source end |
Instance Method Details
#alternately(*args, &block) ⇒ Object Also known as: or
A proxy for phrase.alternately . The Phrase#alternately method is invoked against the Instruction’s containing Phrase with the arguments provided
53 54 55 56 |
# File 'lib/madderlib/instruction.rb', line 53 def alternately(*args, &block) # proxy to the phrase self.phrase.or *args, &block end |
#speak(context) ⇒ Object
Generates the list of words for this Instruction.
This method returns a flattened Array of all the Instruction’s words, resolved as of ‘now’. All blank and nil values are removed from the Array
A thorough description of how words are resolved can be find in the wordify method
Example:
builder = madderlib do
say nil
say ''
end
builder.words.should eql([])
builder = madderlib do
say 'one'
say :two
say 3
end
builder.words.should eql(%w{ one two 3 })
builder = madderlib do
say []
say [ nil, 'one' ]
say [ :two, [ '', 3 ]]
end
builder.words.should eql(%w{ one two 3 })
builder = madderlib do
say madderlib { say 'one' }
say madderlib {
say madderlib { say :two }
say madderlib { say 3 }
}
end
builder.words.should eql(%w{ one two 3 })
words = [ 'one', lambda { :two }, madderlib { say 3 } ]
builder = madderlib do
say { words.shift }.repeat { ! words.empty? }
end
builder.words.should eql(%w{ one two 3 })
103 104 105 106 107 |
# File 'lib/madderlib/instruction.rb', line 103 def speak(context) # wordify everything, and strip out blanks & nils spoken = self.class.wordify(words, context) spoken.find_all {|word| word && (! word.empty?) } end |