We want to have a DSL where we can write statements separated with space. Like this:

1
2
3
4
5
6
Robot.new do
	a b c
	d e
	f g h i
	j
end.run

outputs

1
2
3
4
5
6
7
8
9
10
Go to a
Go to b
Go to c
Go to d
Go to e
Go to f
Go to g
Go to h
Go to i
Go to j

Since separating by space means method invocation in Ruby, we need to hack into method_missing.

I am just posting the codes and will not give it further explanation. Look into the details yourself.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
class Robot
	attr_accessor :movements
	def initialize &block
		@movements = []
		@last_length = 0
		instance_eval &block if block
		rearrange
	end
	def method_missing name, *args
		case args.size
		when 0
			rearrange
			@movements.push result = Movement.new(name)
			@last_length += 1
			result
		when 1
			@movements.push result = Movement.new(name)
			@last_length += 1
			result
		else
			super
		end
	end
	def rearrange
		last_movements = @movements.last @last_length
		@movements[@movements.size - @last_length..] = last_movements.reverse
		@last_length = 0
	end
	def run
		puts @movements
	end
	class Movement
		attr_accessor :target
		def initialize target
			@target = target
		end
		def to_s
			"Go to #@target"
		end
	end
end

Similar tricks are used in my other Ruby project alda-rb. The codes can be found on GitHub.