Class: MadderLib::Grammar

Inherits:
Object
  • Object
show all
Defined in:
lib/madderlib/core.rb

Overview

Grammar

A class for registering MadderLib Builders.

It is intended to help de-couple Ruby scripts which generate Builders from those which use them.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeGrammar

Constructs a new Grammar



123
124
125
126
127
128
129
# File 'lib/madderlib/core.rb', line 123

def initialize
	@builders = []
	@builder_map = {}

	#	randomness
	srand(Time.now.to_i)
end

Instance Attribute Details

#builder_mapObject (readonly)

A Hash of all the Builders in the Grammar which have an id



120
121
122
# File 'lib/madderlib/core.rb', line 120

def builder_map
  @builder_map
end

#buildersObject (readonly)

An Array of all Builders in the Grammar



118
119
120
# File 'lib/madderlib/core.rb', line 118

def builders
  @builders
end

Class Method Details

.get_instanceObject

Returns the active Grammar instance

If no such Grammar exists, a new one is created

See: new_instance



112
113
114
# File 'lib/madderlib/core.rb', line 112

def get_instance
	@instance ||= new_instance
end

.new_instanceObject

Constructs a new Grammar instance

The new instance becomes the active Grammar, as accessible from get_instance

Examples:

current = MadderLib::Grammar.new_instance
current.should have(0).builders
current.should equal(MadderLib::Grammar.get_instance)

one = madderlib { say 'one' }
current.should have(1).builders
current.builders.include?(one).should be_true

fresh = MadderLib::Grammar.new_instance
fresh.should equal(MadderLib::Grammar.get_instance)

two = madderlib { say 'two' }
fresh.should have(1).builders
fresh.builders.include?(two).should be_true

current.should_not equal(MadderLib::Grammar.get_instance)
current.builders.include?(two).should_not be_true


103
104
105
# File 'lib/madderlib/core.rb', line 103

def new_instance
	@instance = self.new
end

Instance Method Details

#[](key) ⇒ Object

Provides convenient access to the Builder map (builder_map).

Examples:

grammar = MadderLib::Grammar.new_instance

builder = grammar.add(:id) { say 'has id' }
grammar[:id].should equal(builder)


191
192
193
# File 'lib/madderlib/core.rb', line 191

def [](key)
	@builder_map[key]
end

#add(*args, &block) ⇒ Object Also known as: <<

Adds a Builder to the Grammar.

How this is done depends on the arguments passed

  • if an existing Builder is provided, it is added to the Grammar (as-is)

  • if nothing is provided, then a new Builder is constructed (without any id)

  • otherwise, any argument passed is treated as the id for a newly-constructed Builder

If a block is provided, and a Builder is constructed, that block is leveraged a la Builder#extend

Examples:

grammar = MadderLib::Grammar.new_instance

builder = madderlib { say 'exists' }
x = grammar.add(builder)
x.should equal(builder)
grammar.should have(1).builders
grammar.builder_map.should have(0).keys

builder = grammar.add { say 'no id' }
grammar.should have(2).builders
grammar.builder_map.should have(0).keys
builder.sentence.should eql('no id')

builder = grammar << :id
grammar.should have(3).builders
grammar.builder_map.values.include?(builder).should be_true
builder.sentence.should eql('')


158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/madderlib/core.rb', line 158

def add(*args, &block)
	builder = args.first

	case builder
		when Builder
			#	leave it alone
		when nil
			#	new, with block dispatched
			builder = Builder.new &block
		else
			#	new, assume the arg is an ID
			builder = Builder.new args.first, &block
	end

	unless @builders.include?(builder)
		@builders << builder

		#	an id is not required
		id = builder.id
		(@builder_map[id] = builder) if id
	end

	builder
end

#freezeObject Also known as: close, complete

Freezes, and closes / completes, the current Grammar

The Grammar becomes immutable. As a side-effect, if it is the current Grammar, a new_instance is created and used from this point forwards



199
200
201
202
203
204
205
206
207
208
209
# File 'lib/madderlib/core.rb', line 199

def freeze
	super

	#	deep freeze
	[@builders, @builder_map].each {|o| o.freeze }

	if self.class.get_instance == self
		#	we can no longer be the current Grammar
		self.class.new_instance
	end
end