whateverblog.
Using Ruby to write C#
Friday, August 22, 2003 05:57 PM

Lately I've gotten used to using Ruby to generate particularly mind-numbing chunks of C# code. For example, if I had to write the following:

// Red Flag
flagRed.Name = "Red";
flagRed.Text = "Red";
flagRed.OnSelected += new FlagSelectionHandler(flagRed).Handler;
flagRed.Image = "flagRed.jpg";
flags.Add(flagRed);

// Blue Flag
flagBlue.Name = "Blue";
flagBlue.Text = "Blue";
flagBlue.OnSelected += new FlagSelectionHandler(flagBlue).Handler;
flagBlue.Image = "flagBlue.jpg";
flags.Add(flagBlue);

// ...and so on for green, yellow, orange, purple...

I can just fire up irb and type the following:

template = <<TEMPLATE
// @ Flag
flag@.Name = "@";
flag@.Text = "@";
flag@.OnSelected += new FlagSelectionHandler(flag@).Handler;
flag@.Image = "flag@.jpg";
flags.Add(flag@);
TEMPLATE

['Red', 'Blue', 'Green', 'Yellow', 'Orange', 'Purple'].each do |color|
	puts template.gsub(/\@/, color)
end

and cut and paste the result to Visual Studio. So easy.

I also wanted to share this little bit of Ruby that parses Unicode script data and writes C# code with the result:

require 'net/http'

# get latest script from web
h = Net::HTTP.new('www.unicode.org', 80)
resp, data = h.get('/Public/UNIDATA/Scripts.txt', nil)
if resp.code !~ /^200/
	raise "Error code: #{resp.code}"
end

list = []
scripts = []

# the full text is in 'data' var
data.each_with_index do |line, i|

	# skip comments and all-whitespace lines
	next if line !~ /[^\s]/ or line =~ /^#/

	# parse single-point
	if line =~ /^([0-9A-F]{4,})\s*;\s*(\w*)/
		range = [$1, $1]
		script = $2
	# parse range
	elsif line =~ /^([0-9A-F]{4,})\.\.([0-9A-F]{4,})\s*;\s*(\w*)/
		range = [$1, $2]
		script = $3
	else
		raise "Parse error on line #{i + 1}: #{line}"
	end
	
	list << [range, script]
	scripts << script
end

scripts.uniq!  # remove duplicates

# now print C#

list.each do |x|
	(low, high), script = x
	if (low == high)
		puts "scripts.Add(0x#{low}, Script.#{script});"
	else
		puts "scripts.Add(0x#{low}, 0x#{high}, Script.#{script});"
	end
end

puts
puts scripts.join(",\n")

This is the kind of thing at which Ruby really excels: banging out one-off text processing apps.