Reputation: 1327
I'm writing an IRCd. For this topic it doesn't really matter if you know much about IRC. Its a simple code style problem.
Quick overview of the problem:
I currently concocted this marvelous piece of code, it works perfectly. However, its just not "ruby-like". This piece of code is more what you expect in some piece of C code.
# 11 is the number of all fixed characters combined in the reply
pre_length = 11 + servername.length + mynick.length + channel.name.length
list = [""]
i = 0
channel.nicks.each do |nick, client|
list[i+=1] = "" if list[i].length + nick.length + pre_length > 500
list[i] << "#{channel.mode_char(client)}#{client.nick} "
end
list.each { |l| send_numeric(RPL_NAMREPLY, channel.name, l.strip) }
send_numeric(RPL_ENDOFNAMES, channel.name)
So my question is, any ideas to do this more nicely?
PS. code has been slightly modified to make it easier to understand out-of-context
Upvotes: 1
Views: 173
Reputation: 177715
I can’t think of a way to simplify the logic, but the Enumerable#inject
method captures the pattern of “building up a result while traversing a list”:
stuff = %w(my list of words)
list = stuff.inject([""]) do |result,obj|
tsst = result[-1] + " " + obj
if tsst.length > 500 then result << obj else result[-1] = tsst end
result
end
(Here I’m just working on an array of strings.)
Upvotes: 1
Reputation: 2381
To split a string into 512 char strings you can use some Enumerator magic. This requires Ruby 1.8.7 or greater:
long_string.each_char.each_slice(512).map{ |chunk| chunk.join }
Upvotes: 0